You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2010/01/19 10:43:34 UTC

svn commit: r900710 - in /commons/sandbox/runtime/trunk/src/main/native: Makefile.msc.in configure os/unix/uutils.c os/win32/main.rc os/win32/subproc.c os/win32/wutil.c support/ support/win32/ support/win32/support.rc support/win32/wsuexec.c

Author: mturk
Date: Tue Jan 19 09:43:33 2010
New Revision: 900710

URL: http://svn.apache.org/viewvc?rev=900710&view=rev
Log:
Add support dir

Added:
    commons/sandbox/runtime/trunk/src/main/native/support/
    commons/sandbox/runtime/trunk/src/main/native/support/win32/
    commons/sandbox/runtime/trunk/src/main/native/support/win32/support.rc
    commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
    commons/sandbox/runtime/trunk/src/main/native/configure
    commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/main.rc
    commons/sandbox/runtime/trunk/src/main/native/os/win32/subproc.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=900710&r1=900709&r2=900710&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Tue Jan 19 09:43:33 2010
@@ -35,6 +35,7 @@
 LINK="@link@"
 PREFIX=@prefix@
 LIBDIR=@libdir@
+BINDIR=@bindir@
 TOPDIR=@topdir@
 CPP=@cpp@
 CXX=@cxx@
@@ -69,6 +70,7 @@
 SQLMODLIB=$(SQLNAME)$(SO)
 EXPORTS=/EXPORT:SubprocMainW
 TESTSUITE=testsuite$(EXE)
+WINSUEXEC=wsuexec$(EXE)
 
 COMMON_OBJS=\
 	$(SRCDIR)/shared/buildmark.$(OBJ) \
@@ -286,17 +288,25 @@
 	IF EXIST $(SQLMODLIB).manifest \
 		mt -nologo -manifest $@.manifest -outputresource:$@;2
 
+$(WINSUEXEC):  $(SRCDIR)/support/win32/wsuexec.$(OBJ)
+	$(RC) /l 0x409 /d "NDEBUG" /d STR_PRODUCT="\"Apache Commons Runtime suEXEC\"" /d STR_INTNAME="\"wsuexec\"" /i "$(SRCDIR)\support\win32" /i "$(SRCDIR)\include" /fo $@.res $(SRCDIR)/support/win32/support.rc
+	$(LINK) $(SHFLAGS) /SUBSYSTEM:WINDOWS $(LDFLAGS) /pdb:wsuexec.pdb /out:$@ @<<
+	$(SRCDIR)/support/win32/wsuexec.$(OBJ) $@.res
+<<
+	IF EXIST $@.manifest \
+		mt -nologo -manifest $@.manifest -outputresource:$@;1
 
 $(TESTSUITE):  $(SHAREDLIB) @modules@ $(SRCDIR)/test/testsuite.$(OBJ)
 	$(LINK) $(SHFLAGS) /SUBSYSTEM:CONSOLE $(LDFLAGS) /libpath:"." $(LIBNAME).lib /pdb:testsuite.pdb /out:$@ @<<
 	$(SRCDIR)/test/testsuite.$(OBJ)
 <<
 	IF EXIST $@.manifest \
-		mt -nologo -manifest $@.manifest -outputresource:$@;2
+		mt -nologo -manifest $@.manifest -outputresource:$@;1
 
 
 test: $(TESTSUITE)
 
+tools: $(WINSUEXEC)
 
 clean:
 	-@del /Q $(SRCDIR)\port\*.$(OBJ) 2>NUL
@@ -310,6 +320,7 @@
 	-@del /Q $(SRCDIR)\srclib\expat\*.$(OBJ) 2>NUL
 	-@del /Q $(SRCDIR)\srclib\regex\*.$(OBJ) 2>NUL
 	-@del /Q $(SRCDIR)\srclib\zlib\*.$(OBJ) 2>NUL
+	-@del /Q $(SRCDIR)\support\win32\*.$(OBJ) 2>NUL
 	-@del /Q *.dll  2>NUL
 	-@del /Q *.lib  2>NUL
 	-@del /Q *.pdb  2>NUL

Modified: commons/sandbox/runtime/trunk/src/main/native/configure
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/configure?rev=900710&r1=900709&r2=900710&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/configure (original)
+++ commons/sandbox/runtime/trunk/src/main/native/configure Tue Jan 19 09:43:33 2010
@@ -58,6 +58,7 @@
 name=acr
 prefix="${PREFIX:=/usr/local}"
 libdir="lib"
+bindir="bin"
 cc="${CC:=gcc}"
 cxx="${CXX:=g++}"
 ar="${AR:=ar}"
@@ -171,6 +172,10 @@
             libdir="$a"
             shift
         ;;
+        --bindir=*  )
+            bindir="$a"
+            shift
+        ;;
         --with-arch=* )
             mach="$a"
             shift
@@ -1287,6 +1292,7 @@
     -e 's|@bits@|'"$bits"'|g' \
     -e 's|@ranlib@|'"$ranlib"'|g' \
     -e 's|@prefix@|'"$prefix"'|g' \
+    -e 's|@bindir@|'"$bindir"'|g' \
     -e 's|@libdir@|'"$libdir"'|g' \
     -e 's|@topdir@|'"$topdir"'|g' \
     -e 's|@asflags@|'"$asflags"'|g' \

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c?rev=900710&r1=900709&r2=900710&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c Tue Jan 19 09:43:33 2010
@@ -50,7 +50,7 @@
     time(&timevar);
     lt = localtime(&timevar);
 
-    fprintf(stream, "[%d:%u] [%d-%.2d-%.2d %.2d:%.2d:%.2d]: ",
+    fprintf(stream, "[%d:%u] [%d-%.2d-%.2d %.2d:%.2d:%.2d] ",
             getpid(), ACR_GETTID(),
             lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday,
             lt->tm_hour, lt->tm_min, lt->tm_sec);

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/main.rc
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/main.rc?rev=900710&r1=900709&r2=900710&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/main.rc (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/main.rc Tue Jan 19 09:43:33 2010
@@ -35,7 +35,7 @@
   "limitations under the License."
 
 #define STR_COPYRIGHT \
-  "Copyright © 2009 Apache Software Foundation.\r\n"                           \
+  "Copyright © 2010 Apache Software Foundation.\r\n"                           \
   "See the NOTICE file distributed with this work for additional "             \
   "information regarding copyright ownership."
 

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/subproc.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/subproc.c?rev=900710&r1=900709&r2=900710&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/subproc.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/subproc.c Tue Jan 19 09:43:33 2010
@@ -158,37 +158,38 @@
         goto cleanup;
     }
 
-    for (i = 2; i < argc; i++) {
-        if ((argv[i][0] == L'/' && argv[i][1] == L'/') ||
-            (argv[i][0] == L'-' && argv[i][1] == L'-')) {
+    for (i = 2; i < argc && rc == 0; i++) {
+        if (argv[i][0] == L'-' && argv[i][1] == L'-') {
             wchar_t *opt;
             wchar_t *cmd = argv[i] + 2;
             if (!*cmd) {
-                /* Skip Explicit command delimiter
-                 * In case our child needs "//" as first argument
+                /* Skip Explicit command options delimiter
+                 * In case our child needs "--" as first argument
                  */
                 i++;
                 break;
             }
             /* Parse internal command by spliting the
-             * //CMD[:OPT] to CMD and OPT or
              * --CMD[=OPT] to CMD and OPT
              */
-            if ((opt = wcspbrk(cmd, L":=")))
+            if ((opt = wcschr(cmd, L'=')))
                 *(opt++) = '\0';
-            rc = ACR_EINVAL;
             switch (*cmd) {
-                case L'P':
-                    if (!opt)
+                case L'p':
+                    if (!opt) {
+                        rc = ACR_EINVAL;
                         goto cleanup;
+                    }
                     ppid = _wtoi(opt);
                 break;
-                case L'T':
-                    if (!opt)
+                case L't':
+                    if (!opt) {
+                        rc = ACR_EINVAL;
                         goto cleanup;
+                    }
                     child.limit.timeout = _wtoi64(opt);
                 break;
-                case L'I':
+                case L'i':
                     /* Where the child stdin should be redirected
                      * Note that since known we don't pass the \\.\pipe\
                      * prefix so we need to recreate the full name here.
@@ -202,7 +203,7 @@
                         child.flags |= ACR_PROC_HAS_STDIN;
                     }
                 break;
-                case L'O':
+                case L'o':
                     /* Where the child stdout should be redirected */
                     if (opt) {
                         wcslcpy(po_name, pfx, sizeof(po_name));
@@ -210,7 +211,7 @@
                         child.flags |= ACR_PROC_HAS_STDOUT;
                     }
                 break;
-                case L'E':
+                case L'e':
                     /* Where the child stderr should be redirected */
                     if (opt) {
                         wcslcpy(pe_name, pfx, sizeof(pe_name));
@@ -220,12 +221,15 @@
                     else
                         child.flags |= ACR_PROC_NUL_STDERR;
                 break;
-                case L'D':
+                case L'd':
                     /* Detached process */
                     child.flags |= ACR_PROC_DETACHED;
                 break;
                 default:
-                    /* Unknown argument */
+                    /* Unknown argument.
+                     * stop processing
+                     */
+                    rc = ACR_EOF;
                 break;
             }
         }
@@ -778,11 +782,11 @@
                            dll_dos_modname, L",SubprocMainW", NULL);
     /* Add our pid to the child arguments */
     suba[subn] = s_malloc(wchar_t, 32);
-    _snwprintf(suba[subn++], 32, L"--P:%d", GetCurrentProcessId());
+    _snwprintf(suba[subn++], 32, L"--p=%d", GetCurrentProcessId());
     if (ep->limit.timeout > 0) {
         /* Add Timeout only if set */
         suba[subn] = s_malloc(wchar_t, 32);
-        _snwprintf(suba[subn++], 32, L"--T:%I64d",ep->limit.timeout);
+        _snwprintf(suba[subn++], 32, L"--t=%I64d",ep->limit.timeout);
     }
 
     if (ep->limit.timeout > 0) {
@@ -799,7 +803,7 @@
                            0)))
             goto cleanup;
         suba[subn] = s_malloc(wchar_t, 64);
-        _snwprintf(suba[subn++], 64, L"--I:%s", childpname[PIPE_STDINP_RPC] + 9);
+        _snwprintf(suba[subn++], 64, L"--i=%s", childpname[PIPE_STDINP_RPC] + 9);
     }
     if (ep->flags & ACR_PROC_HAS_STDOUT) {
         if ((rc = pipepair(&childpipes[PIPE_STDOUT_RPC],
@@ -808,7 +812,7 @@
                            ACR_PIPE_WRITE_BLOCK)))
             goto cleanup;
         suba[subn] = s_malloc(wchar_t, 64);
-        _snwprintf(suba[subn++], 64, L"--O:%s", childpname[PIPE_STDOUT_RPC] + 9);
+        _snwprintf(suba[subn++], 64, L"--o=%s", childpname[PIPE_STDOUT_RPC] + 9);
     }
     if (ep->flags & ACR_PROC_HAS_STDERR) {
         if ((rc = pipepair(&childpipes[PIPE_STDERR_RPC],
@@ -817,11 +821,11 @@
                            ACR_PIPE_WRITE_BLOCK)))
             goto cleanup;
         suba[subn] = s_malloc(wchar_t, 64);
-        _snwprintf(suba[subn++], 64, L"--E:%s", childpname[PIPE_STDERR_RPC] + 9);
+        _snwprintf(suba[subn++], 64, L"--e=%s", childpname[PIPE_STDERR_RPC] + 9);
     }
     else if (ep->flags & ACR_PROC_NUL_STDERR) {
         /* --E without pipe name will force NUL for stderr */
-        suba[subn++] = x_wcsdup(L"--E");
+        suba[subn++] = x_wcsdup(L"--e");
     }
     suba[subn++] = ACR_wcsdup(executable);
     suba[subn] = NULL;

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c?rev=900710&r1=900709&r2=900710&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c Tue Jan 19 09:43:33 2010
@@ -44,7 +44,7 @@
     lt = localtime(&timevar);
     ep = bp + ACR_HBUFF_SIZ;
     snprintf(bp, (size_t)(ep - bp),
-             "[%u:%u] [%d-%.2d-%.2d %.2d:%.2d:%.2d]: ",
+             "[%u:%u] [%d-%.2d-%.2d %.2d:%.2d:%.2d] ",
              GetCurrentProcessId(), GetCurrentThreadId(),
              lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday,
              lt->tm_hour, lt->tm_min, lt->tm_sec);

Added: commons/sandbox/runtime/trunk/src/main/native/support/win32/support.rc
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/support/win32/support.rc?rev=900710&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/support/win32/support.rc (added)
+++ commons/sandbox/runtime/trunk/src/main/native/support/win32/support.rc Tue Jan 19 09:43:33 2010
@@ -0,0 +1,113 @@
+/* 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.
+ *
+ */
+
+#include <windows.h>
+#include "acr_version.h"
+
+#define STR_LICENSE \
+  "Licensed 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\r\n"                                \
+  "\r\n"                                                                       \
+  "http://www.apache.org/licenses/LICENSE-2.0\r\n"                             \
+  "\r\n"                                                                       \
+  "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."
+
+#define STR_COPYRIGHT \
+  "Copyright © 2010 Apache Software Foundation.\r\n"                           \
+  "See the NOTICE file distributed with this work for additional "             \
+  "information regarding copyright ownership."
+
+#define STR_COMPANY         "Apache Software Foundation"
+#define STR_TRADEMARK       "™ Apache Software Foundation"
+#ifndef STR_PRODUCT
+#define STR_PRODUCT         "Apache Commons Runtime"
+#endif
+#ifndef STR_INTNAME
+#define STR_INTNAME         "acr"
+#endif
+#ifndef STR_BINNAME
+#define STR_BINNAME         STR_INTNAME ".exe"
+#endif
+
+#define PRIVATE_BUILD       ACR_IS_DEV_VERSION
+#define PRERELEASE_BUILD    ACR_IS_DEV_VERSION
+
+#if PRIVATE_BUILD
+#define STR_PRIVATE   "Initial Prerelease"
+#define STR_SPECIAL   "Basic functionality"
+#define STD_FILEFLAGS VS_FF_PRIVATEBUILD | VS_FF_SPECIALBUILD
+#else
+#define STD_FILEFLAGS 0x0L
+#endif
+
+#if PRERELEASE_BUILD
+#define PSTD_FILEFLAGS STD_FILEFLAGS | VS_FF_PRERELEASE
+#else
+#define PSTD_FILEFLAGS STD_FILEFLAGS
+#endif
+
+#ifdef _DEBUG
+#define APP_FILEFLAGS STD_FILEFLAGS | VS_FF_DEBUG
+#else
+#define APP_FILEFLAGS STD_FILEFLAGS
+#endif
+
+#define IDI_MAINICON 101
+
+IDI_MAINICON         ICON                       "apache.ico"
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST  "support.manifest"
+
+1 VERSIONINFO
+ FILEVERSION ACR_VERSION_STRING_CSV
+ PRODUCTVERSION ACR_VERSION_STRING_CSV
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS APP_FILEFLAGS
+ FILEOS VOS_NT
+ FILETYPE VFT_APP
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "Comments",  STR_LICENSE "\0"
+            VALUE "CompanyName", STR_COMPANY "\0"
+            VALUE "FileDescription", STR_PRODUCT "\0"
+            VALUE "FileVersion", ACR_VERSION_STRING "\0"
+            VALUE "InternalName", STR_INTNAME "\0"
+            VALUE "LegalCopyright", STR_COPYRIGHT "\0"
+            VALUE "LegalTrademarks", STR_TRADEMARK "\0"
+            VALUE "OriginalFilename", STR_BINNAME "\0"
+            VALUE "ProductName", STR_PRODUCT "\0"
+            VALUE "ProductVersion", ACR_VERSION_STRING "\0"
+#if PRIVATE_BUILD
+            VALUE "PrivateBuild", STR_PRIVATE "\0"
+            VALUE "SpecialBuild", STR_SPECIAL "\0"
+#endif
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+

Added: commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c?rev=900710&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c Tue Jan 19 09:43:33 2010
@@ -0,0 +1,525 @@
+/* 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.
+ */
+
+/**
+ * Utility similar to rundll32.exe that can run executables as well.
+ * It also allows to run executables inside different session from
+ * the one the caller is running.
+ * It was inspired by the suEXEC Apache Httpd utility with the less restrictive
+ * constrains that are available inside Microsoft Windows operating systems.
+ *
+ * Contributed by Mladen Turk mturk@redhat.com
+ */
+
+#if !defined(UNICODE)
+#define UNICODE
+#endif
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+
+/*
+ * ---------------------------------------------------------------------
+ * Begin of argument processing code
+ * ---------------------------------------------------------------------
+ */
+
+#define INCH()                              \
+    do {                                    \
+        n = ((c = *arg) != 0) ? 1 : 0;      \
+    } while (0)
+
+#define PUTC(x)                             \
+    do {                                    \
+        ++rv;                               \
+        if (bufsize != 0) {                 \
+            if (bufsize < 1 ||              \
+                (bufsize == 1 &&            \
+                (x) != 0)) {                \
+                *buf = 0;                   \
+                bufsize = 0;                \
+            } else {                        \
+                *(buf++) = (x);             \
+                bufsize--;                  \
+            }                               \
+        }                                   \
+    } while (0)
+
+#define SKIP_WHITESPACEW(C)                 \
+    for ( ; *C == L' ' || *C == L'\t'; ) {  \
+        C++;                                \
+    };
+
+#define CHECK_QUOTATIONW(C, Q)              \
+    Q = 0;                                  \
+    if (*C == L'"') {                       \
+        Q = 1;                              \
+        C++;                                \
+    }                                       \
+    else if (*C == L'\'') {                 \
+        Q = 2;                              \
+        C++;                                \
+    }
+
+/* DETERMINE_NEXTSTRING:
+ * At exit, cp will point to one of the following:  NULL, SPACE, TAB or QUOTE.
+ * NULL implies the argument string has been fully traversed.
+ */
+#define DETERMINE_NEXTSTRINGW(C, Q)                                 \
+    for ( ; *C != L'\0'; C++) {                                     \
+        if ((*C == L'\\' && (*(C+1) == L' ' || *(C+1) == L'\t' ||   \
+                             *(C+1) == L'"' || *(C+1) == L'\''))) { \
+            C++;                                                    \
+            continue;                                               \
+        }                                                           \
+        if ((!Q && (*C == L' ' || *C == L'\t'))                     \
+            || (Q == 1 && *C == L'"')                               \
+            || (Q == 2 && *C == L'\'')) {                           \
+            break;                                                  \
+        }                                                           \
+    }
+
+/* REMOVE_ESCAPE_CHARS:
+ * Compresses the arg string to remove all of the '\' escape chars.
+ * The final argv strings should not have any extra escape chars in it.
+ */
+#define REMOVE_ESCAPE_CHARSW(C, D, E)                               \
+    E = 0;                                                          \
+    while(*D) {                                                     \
+        if (!E &&                                                   \
+            (*D == L'\\' && (*(D+1) == L' ' || *(D+1) == L'\t' ||   \
+                             *(D+1) == L'"' || *(D+1) == L'\''))) { \
+            E = 1;                                                  \
+        }                                                           \
+        else {                                                      \
+            E = 0;                                                  \
+            *C++ = *D;                                              \
+        }                                                           \
+        ++D;                                                        \
+    }                                                               \
+    *C = 0
+
+static const wchar_t *const safe_elist[] =
+{
+    /* variable name starts with */
+    L"HTTP_",
+    L"SSL_",
+
+    /* variable name is */
+    L"AUTH_TYPE=",
+    L"CONTENT_LENGTH=",
+    L"CONTENT_TYPE=",
+    L"DATE_GMT=",
+    L"DATE_LOCAL=",
+    L"DOCUMENT_NAME=",
+    L"DOCUMENT_PATH_INFO=",
+    L"DOCUMENT_ROOT=",
+    L"DOCUMENT_URI=",
+    L"GATEWAY_INTERFACE=",
+    L"HTTPS=",
+    L"LAST_MODIFIED=",
+    L"PATH_INFO=",
+    L"PATH_TRANSLATED=",
+    L"QUERY_STRING=",
+    L"QUERY_STRING_UNESCAPED=",
+    L"REMOTE_ADDR=",
+    L"REMOTE_HOST=",
+    L"REMOTE_IDENT=",
+    L"REMOTE_PORT=",
+    L"REMOTE_USER=",
+    L"REDIRECT_HANDLER=",
+    L"REDIRECT_QUERY_STRING=",
+    L"REDIRECT_REMOTE_USER=",
+    L"REDIRECT_STATUS=",
+    L"REDIRECT_URL=",
+    L"REQUEST_METHOD=",
+    L"REQUEST_URI=",
+    L"SCRIPT_FILENAME=",
+    L"SCRIPT_NAME=",
+    L"SCRIPT_URI=",
+    L"SCRIPT_URL=",
+    L"SERVER_ADMIN=",
+    L"SERVER_NAME=",
+    L"SERVER_ADDR=",
+    L"SERVER_PORT=",
+    L"SERVER_PROTOCOL=",
+    L"SERVER_SIGNATURE=",
+    L"SERVER_SOFTWARE=",
+    L"UNIQUE_ID=",
+    L"USER_NAME=",
+    L"TZ=",
+    NULL
+};
+
+static size_t wcsquote(const wchar_t *arg, wchar_t *buf, size_t bufsize)
+{
+    wchar_t c;
+    size_t rv     = 0;
+    size_t quoted = 0;
+    int n;
+
+    /* Empty args are skipped */
+    if (!*arg) {
+        PUTC(L'\0');
+        return 0;
+    }
+    if (wcspbrk(arg, L" \t")) {
+        quoted = 1;
+    }
+    if (quoted) {
+        PUTC(L'"');
+    }
+    for (;;) {
+        INCH();
+        if (n == 0)
+            break;
+
+        if (c == L'"') {
+            PUTC(L'\\');
+        }
+        else if (c == L'\\') {
+            const wchar_t *bsp = arg;
+            /* Add extra backslash for each backslash
+             * followed by double quoute.
+             */
+            while (*bsp && *bsp == L'\\')
+                bsp++;
+            if (*bsp == L'"') {
+                PUTC(L'\\');
+            }
+
+        }
+        PUTC(c);
+        arg++;
+    }
+    if (quoted) {
+        PUTC(L'"');
+    }
+    /* Put NUL terminator, but don't count the NUL. */
+    PUTC(L'\0');
+    rv--;
+
+    return rv;
+}
+
+static wchar_t *wcspbrk_s(const wchar_t *s1, const wchar_t *s2)
+{
+    const wchar_t *scanp;
+    int inquote = 0;
+    int c, sc, pc = *s1;
+
+    /* Some early sanity check */
+    if (!s1 || !*s1)
+        return NULL;
+    while ((c = *s1++) != 0) {
+        for (scanp = s2; (sc = *scanp++) != L'\0';) {
+            if (sc == c && inquote == 0)
+                return (wchar_t *)(s1 - 1);
+        }
+        /* Don't update the previous marker if it was \' already
+         * In that case we have escaped single quote.
+         */
+        if (c == L'\'' && pc != L'\\')
+            inquote = !inquote;
+        pc = c;
+    }
+    return NULL;
+}
+
+static wchar_t *getword(wchar_t **line)
+{
+    wchar_t *cleaned;
+    wchar_t *dirty;
+    wchar_t *argp;
+    wchar_t *args = *line;
+    wchar_t *word;
+    int      escaped;
+    int      isquoted;
+
+    if (!*args)
+        return NULL;
+    SKIP_WHITESPACEW(args);
+    CHECK_QUOTATIONW(args, isquoted);
+    argp = args;
+    DETERMINE_NEXTSTRINGW(args, isquoted);
+    word = argp;
+    if (*args)
+        *(args++) = L'\0';
+
+    cleaned = dirty = word;
+    REMOVE_ESCAPE_CHARSW(cleaned, dirty, escaped);
+
+    *line = args;
+    return word;
+}
+
+/*
+ * Input string is freed if expansion took place
+ */
+static wchar_t *eexpand(wchar_t *str)
+{
+    if (str == NULL)
+        return NULL;
+    /* Check for the possible %FOO% */
+    if (wcschr(str, L'%')) {
+        wchar_t *buf;
+        DWORD    siz;
+
+        siz = ExpandEnvironmentStringsW(str, NULL, 0);
+        if (siz) {
+            buf = (wchar_t *)malloc(siz * sizeof(wchar_t));
+            if (buf == NULL) {
+                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                return str;
+            }
+            siz = ExpandEnvironmentStringsW(str, buf, siz);
+            if (siz == 0) {
+                free(buf);
+                return str;
+            }
+            free(str);
+            return buf;
+        }
+    }
+    return str;
+}
+
+static wchar_t **mergeargs(const wchar_t *const *argv1,
+                           const wchar_t *const *argv2)
+{
+    size_t    argnum = 0;
+    wchar_t **dupargv  = NULL;
+    const wchar_t *const *ap1 = argv1;
+    const wchar_t *const *ap2 = argv2;
+
+    if (!argv1)
+        return NULL;
+    while (*ap1) {
+        if (**ap1)
+            ++argnum;
+        ap1++;
+    }
+
+    if (ap2) {
+        while (*ap2) {
+            if (**ap2)
+                ++argnum;
+            ap2++;
+        }
+    }
+    if (!argnum) {
+        /* Nothing to duplicate
+         */
+        return NULL;
+    }
+    dupargv = malloc((argnum + 1) * sizeof(wchar_t *));
+    if (!dupargv) {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return NULL;
+    }
+    argnum = 0;
+    ap1 = argv1;
+    ap2 = argv2;
+    if (ap1) {
+        while (*ap1) {
+            if (**ap1) {
+                dupargv[argnum++] = (wchar_t *)*ap1;
+            }
+            ap1++;
+        }
+    }
+    if (ap2) {
+        while (*ap2) {
+            if (**ap2) {
+                dupargv[argnum++] = (wchar_t *)*ap2;
+            }
+            ap2++;
+        }
+    }
+    /* Add terminating NULL pointer.
+     */
+    dupargv[argnum] = NULL;
+
+    return dupargv;
+}
+
+static wchar_t *argstostr(const wchar_t *const *argv)
+{
+    size_t argnum = 0;
+    size_t length = 0;
+    size_t arglen = 0;
+    const wchar_t *const *ap = argv;
+    wchar_t *args, *cp;
+
+    if (!ap) {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return NULL;
+    }
+    while (*ap) {
+        size_t al = (*ap, NULL, 0);
+        if (al == (size_t) -1) {
+            SetLastError(ERROR_INVALID_PARAMETER);
+            return NULL;
+        }
+        length += (al + 1);
+        ap++;
+    }
+    if (length == 0)
+        return NULL;
+    args = cp = malloc((length + 1) * sizeof(wchar_t));
+    if (!args) {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return NULL;
+    }
+    ap = argv;
+
+    while (*ap) {
+        if (argnum++) {
+            *(cp++) = L' ';
+            --length;
+        }
+        arglen = wcsquote(*ap, cp, length);
+        cp += arglen;
+        length -= arglen;
+        ap++;
+    }
+    *cp = L'\0';
+    return args;
+}
+
+static int strtoargs(const wchar_t *cmdline,
+                     int nparams,
+                     const wchar_t *const *params,
+                     wchar_t ***argv)
+{
+    const wchar_t *cp;
+    wchar_t *args;
+    wchar_t *cmds;
+    int isquoted, numargs, argnum, argidx = 0;
+
+    SKIP_WHITESPACEW(cmdline);
+    cp = cmdline;
+
+    /* This is ugly and expensive, but if anyone wants to figure a
+     * way to support any number of args without counting and
+     * allocating, please go ahead and change the code.
+     *
+     * Must account for the trailing NULL arg.
+     */
+    numargs = 1;
+    while (*cp != L'\0') {
+        CHECK_QUOTATIONW(cp, isquoted);
+        DETERMINE_NEXTSTRINGW(cp, isquoted);
+        if (*cp != L'\0') {
+            cp++;
+        }
+        numargs++;
+        SKIP_WHITESPACEW(cp);
+    }
+    if (!argv) {
+        /* We are only interested in the number of arguments
+         */
+        return numargs;
+    }
+    cmds = wcsdup(cmdline);
+    if (!cmds) {
+        return -1;
+    }
+    *argv = calloc(numargs, sizeof(wchar_t *));
+    if (!*argv) {
+        x_free(cmds);
+        return -1;
+    }
+    args = cmds;
+    /*  determine first argument */
+    for (argnum = 0; argnum < (numargs-1); argnum++) {
+        wchar_t *argument  = getword(&args);
+
+        if (!argument)
+            break;
+        if (*argument == L'%' || *argument == L'$') {
+            cp = argument + 1;
+            if (*cp == L'*' && *(cp + 1) == L'\0') {
+                if (argidx >= nparams)
+                    break;
+                argument = wcsdup(params[argidx++]);
+                for (; argidx < nparams; argidx++) {
+                    wchar_t *as = malloc((wcslen(argument) + wcslen(params[argidx]) + 2) * sizeof(wchar_t));
+                    wcscpy(part, argument);
+                    wcscat(part, L" ");
+                    wcscat(part, params[argidx]);
+                    free(argument);
+                    argument = as;
+                }
+                (*argv)[argnum] = eexpand(argument);
+                continue;
+            }
+            else if (iswdigit(*cp) && *(cp + 1) == L'\0') {
+                argidx = *cp - L'0';
+                if (argidx == 0) {
+                    if (argnum == 0) {
+                        /* Guard against '$0 ...' strings
+                         */
+                        break;
+                    }
+                    (*argv)[argnum] = wcsdup((*argv)[0]);
+                    continue;
+                }
+                else if (argidx <= nparams) {
+                    /* $n <- params[n-1] */
+                    argument = (wchar_t *)params[argidx-1];
+                }
+                else {
+                    /* We have $n without params[n-1]
+                     * Stop processing
+                     */
+                    break;
+                }
+            }
+        }
+        (*argv)[argnum] = eexpand(wcsdup(argument));
+    }
+
+    x_free(cmds);
+    return argnum;
+}
+
+static int _vwcsicmp(const void *arg1, const void *arg2)
+{
+    /* Compare all of both strings: */
+    return _wcsicmp(*((const wchar_t **)arg1),
+                    *((const wchar_t **)arg2));
+}
+
+static void envsort(wchar_t *const **envp)
+{
+    size_t len = 0;
+    wchar_t *const *ea = *envp;
+
+    while (ea[len])
+        len++;
+    qsort((void *)&envp, len, sizeof(wchar_t *), _vwcsicmp);
+}
+
+int WINAPI wWinMain(HINSTANCE hInstance,
+                    HINSTANCE hPrevInstance,
+                    LPWSTR lpCmdLine,
+                    int nCmdShow)
+{
+
+    return 0;
+}
+

Propchange: commons/sandbox/runtime/trunk/src/main/native/support/win32/wsuexec.c
------------------------------------------------------------------------------
    svn:eol-style = native