]> granicus.if.org Git - php/commitdiff
This commit was manufactured by cvs2svn to create branch 'PHP_4_2_0'.
authorSVN Migration <svn@php.net>
Fri, 12 Jul 2002 13:02:46 +0000 (13:02 +0000)
committerSVN Migration <svn@php.net>
Fri, 12 Jul 2002 13:02:46 +0000 (13:02 +0000)
18 files changed:
TSRM/tsrm_config.nw.h [new file with mode: 0644]
TSRM/tsrm_nw.c [new file with mode: 0644]
TSRM/tsrm_nw.h [new file with mode: 0644]
ext/com/dispatch.c [new file with mode: 0644]
ext/mysql/mysql.mak [new file with mode: 0644]
ext/rpc/com/dispatch.c [new file with mode: 0644]
ext/standard/tests/file/002.phpt [new file with mode: 0644]
main/config.nw.h [new file with mode: 0644]
netware/build.bat [new file with mode: 0755]
netware/buildext.bat [new file with mode: 0755]
netware/buildsapi.bat [new file with mode: 0755]
netware/common.mif [new file with mode: 0644]
netware/mktemp.h [new file with mode: 0644]
netware/php4apache.mak [new file with mode: 0644]
netware/pwd.h [new file with mode: 0644]
netware/sys/stat.h [new file with mode: 0644]
netware/tsrm.mak [new file with mode: 0644]
netware/zend.mak [new file with mode: 0644]

diff --git a/TSRM/tsrm_config.nw.h b/TSRM/tsrm_config.nw.h
new file mode 100644 (file)
index 0000000..0681852
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef TSRM_CONFIG_NW_H
+#define TSRM_CONFIG_NW_H
+
+#define HAVE_UTIME 1
+
+/* Though we have alloca(), this seems to be causing some problem with the stack pointer -- hence not using it */
+/* #define HAVE_ALLOCA 1 */
+
+#endif
diff --git a/TSRM/tsrm_nw.c b/TSRM/tsrm_nw.c
new file mode 100644 (file)
index 0000000..c0f69ad
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 4                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2002 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Venkat Raghavan S <rvenkat@novell.com>                      |
+   +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "TSRM.h"
+
+#ifdef NETWARE
+
+#ifdef USE_MKFIFO
+#include <sys/stat.h>
+#elif !defined(USE_PIPE_OPEN)   /* NXFifoOpen */
+#include <nks/fsio.h>
+#endif
+
+#include <nks/vm.h>
+#include <nks/memory.h>
+
+#include <string.h>
+
+#include "mktemp.h"
+
+/* strtok() call in LibC is abending when used in a different address space -- hence using
+   PHP's version itself for now : Venkat (30/4/02) */
+#include "tsrm_strtok_r.h"
+#define tsrm_strtok_r(a,b,c) strtok((a),(b))
+
+#define WHITESPACE  " \t"
+#define MAX_ARGS    10
+
+
+TSRM_API FILE* popen(const char *commandline, const char *type)
+{
+    char *command = NULL, *argv[MAX_ARGS] = {'\0'}, **env = NULL;
+       char *tempName = "sys:/php/temp/phpXXXXXX.tmp";
+    char *filePath = NULL;
+    char *ptr = NULL;
+    int ptrLen = 0, argc = 0, i = 0, envCount = 0, err = 0;
+       FILE *stream = NULL;
+#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
+    int pipe_handle;
+    int mode = O_RDONLY;
+#else
+    NXHandle_t pipe_handle;
+    NXMode_t mode = NX_O_RDONLY;
+#endif
+    NXExecEnvSpec_t envSpec;
+    NXNameSpec_t nameSpec;
+    NXVmId_t newVM = 0;
+
+    /* Check for validity of input parameters */
+    if (!commandline || !type)
+        return NULL;
+
+    /* Get temporary file name */
+    filePath = mktemp(tempName);
+/*consoleprintf ("PHP | popen: file path = %s, mode = %s\n", filePath, type);*/
+       if (!filePath)
+               return NULL;
+
+    /* Set pipe mode according to type -- for now allow only "r" or "w" */
+    if (strcmp(type, "r") == 0)
+#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
+        mode = O_RDONLY;
+#else
+        mode = NX_O_RDONLY;
+#endif
+    else if (strcmp(type, "w") == 0)
+#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
+        mode = O_WRONLY;
+#else
+        mode = NX_O_WRONLY;
+#endif
+    else
+        return NULL;
+
+#ifdef USE_PIPE_OPEN
+    pipe_handle = pipe_open(filePath, mode);
+/*consoleprintf ("PHP | popen: pipe_open() returned %d\n", pipe_handle);*/
+    if (pipe_handle == -1)
+        return NULL;
+#elif defined(USE_MKFIFO)
+    pipe_handle = mkfifo(filePath, mode);
+consoleprintf ("PHP | popen: mkfifo() returned %d\n", pipe_handle);
+    if (pipe_handle == -1)
+        return NULL;
+#else
+    /*
+        - NetWare doesn't require first parameter
+        - Allowing LibC to choose the buffer size for now
+    */
+    err = NXFifoOpen(0, filePath, mode, 0, &pipe_handle);
+/*consoleprintf ("PHP | popen: NXFifoOpen() returned %d\n", err);*/
+    if (err)
+        return NULL;
+#endif
+
+    /* Copy the environment variables in preparation for the spawn call */
+
+    envCount = NXGetEnvCount() + 1;  /* add one for NULL */
+    env = (char**)NXMemAlloc(sizeof(char*) * envCount, 0);
+    if (!env)
+        return NULL;
+
+    err = NXCopyEnv(env, envCount);
+consoleprintf ("PHP | popen: NXCopyEnv() returned %d\n", err);
+    if (err)
+    {
+        NXMemFree (env);
+        return NULL;
+    }
+
+    /* Separate commandline string into words */
+consoleprintf ("PHP | popen: commandline = %s\n", commandline);
+    ptr = tsrm_strtok_r((char*)commandline, WHITESPACE, NULL);
+    ptrLen = strlen(ptr);
+
+    command = (char*)malloc(ptrLen + 1);
+    if (!command)
+    {
+        NXMemFree (env);
+        return NULL;
+    }
+
+    strcpy (command, ptr);
+
+    ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
+    while (ptr && (argc < MAX_ARGS))
+    {
+        ptrLen = strlen(ptr);
+
+        argv[argc] = (char*)malloc(ptrLen + 1);
+        if (!argv[argc])
+        {
+            NXMemFree (env);
+
+            if (command)
+                free (command);
+
+            for (i = 0; i < argc; i++)
+            {
+                if (argv[i])
+                free (argv[i]);
+            }
+
+            return NULL;
+        }
+
+        strcpy (argv[argc], ptr);
+
+        argc++;
+
+        ptr = tsrm_strtok_r(NULL, WHITESPACE, NULL);
+    }
+consoleprintf ("PHP | popen: commandline string parsed into tokens\n");
+    /* Setup the execution environment and spawn new process */
+
+    envSpec.esFlags = 0;    /* Not used */
+    envSpec.esArgc = argc;
+    envSpec.esArgv = (void**)argv;
+    envSpec.esEnv = (void**)env;
+
+    envSpec.esStdin.ssType =
+    envSpec.esStdout.ssType = NX_OBJ_FIFO;
+    envSpec.esStderr.ssType = NX_OBJ_FILE;
+/*
+    envSpec.esStdin.ssHandle =
+    envSpec.esStdout.ssHandle =
+    envSpec.esStderr.ssHandle = -1;
+*/
+    envSpec.esStdin.ssPathCtx =
+    envSpec.esStdout.ssPathCtx =
+    envSpec.esStderr.ssPathCtx = NULL;
+
+#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
+    if (mode == O_RDONLY)
+#else
+    if (mode == NX_O_RDONLY)
+#endif
+    {
+        envSpec.esStdin.ssPath = filePath;
+        envSpec.esStdout.ssPath = stdout;
+    }
+    else /* Write Only */
+    {
+        envSpec.esStdin.ssPath = stdin;
+        envSpec.esStdout.ssPath = filePath;
+    }
+
+    envSpec.esStderr.ssPath = stdout;
+
+    nameSpec.ssType = NX_OBJ_FIFO;
+/*    nameSpec.ssHandle = 0; */ /* Not used */
+    nameSpec.ssPathCtx = NULL;  /* Not used */
+    nameSpec.ssPath = argv[0];
+consoleprintf ("PHP | popen: environment setup\n");
+    err = NXVmSpawn(&nameSpec, &envSpec, 0, &newVM);
+consoleprintf ("PHP | popen: NXVmSpawn() returned %d\n", err);
+    if (!err)
+        /* Get file pointer corresponding to the pipe (file) opened */
+        stream = fdopen(pipe_handle, type);
+
+    /* Clean-up */
+
+    if (env)
+        NXMemFree (env);
+
+    if (pipe_handle)
+#if defined(USE_PIPE_OPEN) || defined(USE_MKFIFO)
+        close(pipe_handle);
+#else
+        NXClose(pipe_handle);
+#endif
+
+    if (command)
+        free (command);
+
+    for (i = 0; i < argc; i++)
+    {
+        if (argv[i])
+            free (argv[i]);
+    }
+consoleprintf ("PHP | popen: all clean-up done, returning...\n");
+    return stream;
+}
+
+TSRM_API int pclose(FILE* stream)
+{
+    int err = 0;
+    NXHandle_t fd = 0;
+
+    /* Get the process associated with this pipe (file) handle and terminate it */
+    fd = fileno(stream);
+    NXClose (fd);
+
+    err = fclose(stream);
+
+    return err;
+}
+
+#endif
diff --git a/TSRM/tsrm_nw.h b/TSRM/tsrm_nw.h
new file mode 100644 (file)
index 0000000..3ced3f2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 4                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2002 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Authors: Venkat Raghavan S <rvenkat@novell.com>                      |
+   +----------------------------------------------------------------------+
+*/
+
+
+#ifndef TSRM_NW_H
+#define TSRM_NW_H
+
+#include "TSRM.h"
+
+TSRM_API FILE* popen(const char *command, const char *type);
+TSRM_API int pclose(FILE* stream);
+
+#endif
diff --git a/ext/com/dispatch.c b/ext/com/dispatch.c
new file mode 100644 (file)
index 0000000..23c3b0d
--- /dev/null
@@ -0,0 +1,627 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 4                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2002 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Wez Furlong <wez@thebrainroom.com>                           |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/* 
+ * This module is used to export PHP objects to COM and DOTNET by exposing
+ * them as objects implementing IDispatch.
+ * */
+
+#include "php.h"
+#include "php_COM.h"
+#include "php_VARIANT.h"
+#include "conversion.h"
+#include "variant.h"
+
+#define COBJMACROS
+#include <unknwn.h> /* IDispatch */
+#include <dispex.h> /* IDispatchEx */
+
+
+typedef struct {
+       /* This first part MUST match the declaration
+        * of interface IDispatchEx */
+       CONST_VTBL struct IDispatchExVtbl *lpVtbl;
+
+       /* now the PHP stuff */
+       
+       THREAD_T engine_thread; /* for sanity checking */
+       zval *object;                   /* the object exported */
+       LONG refcount;                  /* COM reference count */
+
+       HashTable *dispid_to_name;      /* keep track of dispid -> name mappings */
+       HashTable *name_to_dispid;      /* keep track of name -> dispid mappings */
+
+       GUID sinkid;    /* iid that we "implement" for event sinking */
+       
+       int id;
+} php_dispatchex;
+
+static void disp_destructor(php_dispatchex *disp);
+
+static void dispatch_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+       php_dispatchex *disp = (php_dispatchex *)rsrc->ptr;
+       disp_destructor(disp);
+}
+
+static int le_dispatch;
+int php_COM_dispatch_init(int module_number TSRMLS_DC)
+{
+       le_dispatch = zend_register_list_destructors_ex(dispatch_dtor, NULL, "COM:Dispatch", module_number);
+       return le_dispatch;
+}
+
+
+/* {{{ trace */
+static inline void trace(char *fmt, ...)
+{
+       va_list ap;
+       char buf[4096];
+
+       sprintf(buf, "T=%08x ", tsrm_thread_id());
+       OutputDebugString(buf);
+       
+       va_start(ap, fmt);
+       vsnprintf(buf, sizeof(buf), fmt, ap);
+
+       OutputDebugString(buf);
+       
+       va_end(ap);
+}
+/* }}} */
+
+#define FETCH_DISP(methname)   \
+       php_dispatchex *disp = (php_dispatchex*)This; \
+       trace(" PHP:%s %s\n", Z_OBJCE_P(disp->object)->name, methname); \
+       if (tsrm_thread_id() != disp->engine_thread) \
+               return E_UNEXPECTED;
+
+
+static HRESULT STDMETHODCALLTYPE disp_queryinterface( 
+       IDispatchEx *This,
+       /* [in] */ REFIID riid,
+       /* [iid_is][out] */ void **ppvObject)
+{
+       FETCH_DISP("QueryInterface");
+
+       if (IsEqualGUID(&IID_IUnknown, riid) ||
+                       IsEqualGUID(&IID_IDispatch, riid) ||
+                       IsEqualGUID(&IID_IDispatchEx, riid) ||
+                       IsEqualGUID(&disp->sinkid, riid)) {
+               *ppvObject = This;
+               InterlockedIncrement(&disp->refcount);
+               return S_OK;
+       }
+
+       *ppvObject = NULL;
+       return E_NOINTERFACE;
+}
+        
+static ULONG STDMETHODCALLTYPE disp_addref(IDispatchEx *This)
+{
+       FETCH_DISP("AddRef");
+
+       return InterlockedIncrement(&disp->refcount);
+}
+        
+static ULONG STDMETHODCALLTYPE disp_release(IDispatchEx *This)
+{
+       ULONG ret;
+       TSRMLS_FETCH();
+       FETCH_DISP("Release");
+
+       ret = InterlockedDecrement(&disp->refcount);
+       trace("-- refcount now %d\n", ret);
+       if (ret == 0) {
+               /* destroy it */
+               if (disp->id)
+                       zend_list_delete(disp->id);
+       }
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_gettypeinfocount( 
+       IDispatchEx *This,
+       /* [out] */ UINT *pctinfo)
+{
+       FETCH_DISP("GetTypeInfoCount");
+
+       *pctinfo = 0;
+       return S_OK;
+}
+        
+static HRESULT STDMETHODCALLTYPE disp_gettypeinfo( 
+       IDispatchEx *This,
+       /* [in] */ UINT iTInfo,
+       /* [in] */ LCID lcid,
+       /* [out] */ ITypeInfo **ppTInfo)
+{
+       FETCH_DISP("GetTypeInfo");
+       
+       *ppTInfo = NULL;
+       return DISP_E_BADINDEX;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getidsofnames( 
+       IDispatchEx *This,
+       /* [in] */ REFIID riid,
+       /* [size_is][in] */ LPOLESTR *rgszNames,
+       /* [in] */ UINT cNames,
+       /* [in] */ LCID lcid,
+       /* [size_is][out] */ DISPID *rgDispId)
+{
+       UINT i;
+       HRESULT ret = S_OK;
+       TSRMLS_FETCH();
+       FETCH_DISP("GetIDsOfNames");
+
+       for (i = 0; i < cNames; i++) {
+               char *name;
+               unsigned int namelen;
+               zval **tmp;
+               
+               name = php_OLECHAR_to_char(rgszNames[i], &namelen, CP_ACP TSRMLS_CC);
+               
+               /* Lookup the name in the hash */
+               if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == FAILURE) {
+                       ret = DISP_E_UNKNOWNNAME;
+                       rgDispId[i] = 0;
+               } else {
+                       rgDispId[i] = Z_LVAL_PP(tmp);
+               }
+
+               efree(name);
+
+       }
+       
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_invoke( 
+       IDispatchEx *This,
+       /* [in] */ DISPID dispIdMember,
+       /* [in] */ REFIID riid,
+       /* [in] */ LCID lcid,
+       /* [in] */ WORD wFlags,
+       /* [out][in] */ DISPPARAMS *pDispParams,
+       /* [out] */ VARIANT *pVarResult,
+       /* [out] */ EXCEPINFO *pExcepInfo,
+       /* [out] */ UINT *puArgErr)
+{
+       return This->lpVtbl->InvokeEx(This, dispIdMember,
+                       lcid, wFlags, pDispParams,
+                       pVarResult, pExcepInfo, NULL);
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getdispid( 
+       IDispatchEx *This,
+       /* [in] */ BSTR bstrName,
+       /* [in] */ DWORD grfdex,
+       /* [out] */ DISPID *pid)
+{
+       HRESULT ret = DISP_E_UNKNOWNNAME;
+       char *name;
+       unsigned int namelen;
+       zval **tmp;
+       TSRMLS_FETCH();
+       FETCH_DISP("GetDispID");
+
+       name = php_OLECHAR_to_char(bstrName, &namelen, CP_ACP TSRMLS_CC);
+
+       /* Lookup the name in the hash */
+       if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS) {
+               *pid = Z_LVAL_PP(tmp);
+               ret = S_OK;
+       }
+
+       efree(name);
+       
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_invokeex( 
+       IDispatchEx *This,
+       /* [in] */ DISPID id,
+       /* [in] */ LCID lcid,
+       /* [in] */ WORD wFlags,
+       /* [in] */ DISPPARAMS *pdp,
+       /* [out] */ VARIANT *pvarRes,
+       /* [out] */ EXCEPINFO *pei,
+       /* [unique][in] */ IServiceProvider *pspCaller)
+{
+       zval **name;
+       UINT i;
+       int codepage = CP_ACP;
+       zval *retval = NULL;
+       zval ***params = NULL;
+       HRESULT ret = DISP_E_MEMBERNOTFOUND;
+       TSRMLS_FETCH();
+       FETCH_DISP("InvokeEx");
+
+       if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) {
+               /* TODO: add support for overloaded objects */
+
+               trace("-- Invoke: %d %20s flags=%08x args=%d\n", id, Z_STRVAL_PP(name), wFlags, pdp->cArgs);
+               
+               /* convert args into zvals.
+                * Args are in reverse order */
+               params = (zval ***)emalloc(sizeof(zval **) * pdp->cArgs);
+               for (i = 0; i < pdp->cArgs; i++) {
+                       VARIANT *arg;
+                       zval *zarg;
+                       
+                       arg = &pdp->rgvarg[ pdp->cArgs - 1 - i];
+
+                       trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg));
+
+                       ALLOC_INIT_ZVAL(zarg);
+                       
+                       if (V_VT(arg) == VT_DISPATCH) {
+                               trace("arg %d is dispatchable\n", i);
+                               if (NULL == php_COM_object_from_dispatch(V_DISPATCH(arg), zarg TSRMLS_CC)) {
+                                       trace("failed to convert arg %d to zval\n", i);
+                                       ZVAL_NULL(zarg);
+                               }
+                       } else {
+                               // arg can't be an idispatch, so we don't care for the implicit AddRef() call here
+                               if (FAILURE == php_variant_to_pval(arg, zarg, codepage TSRMLS_CC)) {
+                                       trace("failed to convert arg %d to zval\n", i);
+                                       ZVAL_NULL(zarg);
+                               }
+                       }
+                       
+                       params[i] = &zarg;
+               }
+
+               trace("arguments processed, prepare to do some work\n");        
+               
+               if (wFlags & DISPATCH_PROPERTYGET) {
+                       trace("trying to get a property\n");
+                       zend_hash_find(Z_OBJPROP_P(disp->object), Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, (void**)&retval);
+               } else if (wFlags & DISPATCH_PROPERTYPUT) {
+                       trace("trying to set a property\n");
+                       add_property_zval(disp->object, Z_STRVAL_PP(name), *params[0]);
+               } else if (wFlags & DISPATCH_METHOD) {
+                       trace("Trying to call user function\n");
+                       if (SUCCESS == call_user_function_ex(EG(function_table), &disp->object, *name,
+                                       &retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) {
+                               ret = S_OK;
+                       } else {
+                               ret = DISP_E_EXCEPTION;
+                       }
+               } else {
+                       trace("Don't know how to handle this invocation %08x\n", wFlags);
+               }
+       
+               /* release arguments */
+               for (i = 0; i < pdp->cArgs; i++)
+                       zval_ptr_dtor(params[i]);
+               efree(params);
+               
+               /* return value */
+               if (retval) {
+                       if (pvarRes) {
+                               if (Z_TYPE_P(retval) == IS_OBJECT) {
+                                       /* export the object using a dispatch like ourselves */
+                                       VariantInit(pvarRes);
+                                       V_VT(pvarRes) = VT_DISPATCH;
+                                       V_DISPATCH(pvarRes) = php_COM_export_object(retval TSRMLS_CC);
+                               } else {
+                                       php_pval_to_variant(retval, pvarRes, codepage TSRMLS_CC);
+                               }
+                       }
+                       zval_ptr_dtor(&retval);
+               } else if (pvarRes) {
+                       VariantInit(pvarRes);
+               }
+               
+       } else {
+               trace("InvokeEx: I don't support DISPID=%d\n", id);
+       }
+
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_deletememberbyname( 
+       IDispatchEx *This,
+       /* [in] */ BSTR bstrName,
+       /* [in] */ DWORD grfdex)
+{
+       FETCH_DISP("DeleteMemberByName");
+
+       return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_deletememberbydispid( 
+       IDispatchEx *This,
+       /* [in] */ DISPID id)
+{
+       FETCH_DISP("DeleteMemberByDispID");
+       
+       return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getmemberproperties( 
+       IDispatchEx *This,
+       /* [in] */ DISPID id,
+       /* [in] */ DWORD grfdexFetch,
+       /* [out] */ DWORD *pgrfdex)
+{
+       FETCH_DISP("GetMemberProperties");
+
+       return DISP_E_UNKNOWNNAME;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getmembername( 
+       IDispatchEx *This,
+       /* [in] */ DISPID id,
+       /* [out] */ BSTR *pbstrName)
+{
+       zval *name;
+       TSRMLS_FETCH();
+       FETCH_DISP("GetMemberName");
+
+       if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) {
+               OLECHAR *olestr = php_char_to_OLECHAR(Z_STRVAL_P(name), Z_STRLEN_P(name), CP_ACP TSRMLS_CC);
+               *pbstrName = SysAllocString(olestr);
+               efree(olestr);
+               return S_OK;
+       } else {
+               return DISP_E_UNKNOWNNAME;
+       }
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getnextdispid( 
+       IDispatchEx *This,
+       /* [in] */ DWORD grfdex,
+       /* [in] */ DISPID id,
+       /* [out] */ DISPID *pid)
+{
+       ulong next = id+1;
+       FETCH_DISP("GetNextDispID");
+
+       while(!zend_hash_index_exists(disp->dispid_to_name, next))
+               next++;
+
+       if (zend_hash_index_exists(disp->dispid_to_name, next)) {
+               *pid = next;
+               return S_OK;
+       }
+       return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getnamespaceparent( 
+       IDispatchEx *This,
+       /* [out] */ IUnknown **ppunk)
+{
+       FETCH_DISP("GetNameSpaceParent");
+
+       *ppunk = NULL;
+       return E_NOTIMPL;
+}
+        
+static struct IDispatchExVtbl php_dispatch_vtbl = {
+       disp_queryinterface,
+       disp_addref,
+       disp_release,
+       disp_gettypeinfocount,
+       disp_gettypeinfo,
+       disp_getidsofnames,
+       disp_invoke,
+       disp_getdispid,
+       disp_invokeex,
+       disp_deletememberbyname,
+       disp_deletememberbydispid,
+       disp_getmemberproperties,
+       disp_getmembername,
+       disp_getnextdispid,
+       disp_getnamespaceparent
+};
+
+
+/* enumerate functions and properties of the object and assign
+ * dispatch ids */
+static void generate_dispids(php_dispatchex *disp TSRMLS_DC)
+{
+       HashPosition pos;
+       char *name = NULL;
+       zval *tmp;
+       int namelen;
+       int keytype;
+       ulong pid;
+
+       if (disp->dispid_to_name == NULL) {
+               ALLOC_HASHTABLE(disp->dispid_to_name);
+               ALLOC_HASHTABLE(disp->name_to_dispid);
+               zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
+               zend_hash_init(disp->dispid_to_name, 0, NULL, ZVAL_PTR_DTOR, 0);
+       }
+
+       /* properties */
+       zend_hash_internal_pointer_reset_ex(Z_OBJPROP_PP(&disp->object), &pos);
+       while (HASH_KEY_NON_EXISTANT != (keytype =
+                               zend_hash_get_current_key_ex(Z_OBJPROP_PP(&disp->object), &name, &namelen, &pid, 0, &pos))) {
+               char namebuf[32];
+               if (keytype == HASH_KEY_IS_LONG) {
+                       sprintf(namebuf, "%d", pid);
+                       name = namebuf;
+                       namelen = strlen(namebuf);
+               }
+
+               zend_hash_move_forward_ex(Z_OBJPROP_PP(&disp->object), &pos);
+               
+               /* Find the existing id */
+               if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS)
+                       continue;
+               
+               /* add the mappings */
+               MAKE_STD_ZVAL(tmp);
+               ZVAL_STRINGL(tmp, name, namelen, 1);
+               zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL);
+
+               MAKE_STD_ZVAL(tmp);
+               ZVAL_LONG(tmp, pid);
+               zend_hash_update(disp->name_to_dispid, name, namelen+1, (void*)&tmp, sizeof(zval *), NULL);
+
+       }
+       
+       /* functions */
+       zend_hash_internal_pointer_reset_ex(&Z_OBJCE_PP(&disp->object)->function_table, &pos);
+       while (HASH_KEY_NON_EXISTANT != (keytype =
+                               zend_hash_get_current_key_ex(&Z_OBJCE_PP(&disp->object)->function_table, &name, &namelen, &pid, 0, &pos))) {
+
+               char namebuf[32];
+               if (keytype == HASH_KEY_IS_LONG) {
+                       sprintf(namebuf, "%d", pid);
+                       name = namebuf;
+                       namelen = strlen(namebuf);
+               }
+
+               zend_hash_move_forward_ex(Z_OBJPROP_PP(&disp->object), &pos);
+               
+               /* Find the existing id */
+               if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS)
+                       continue;
+               
+               /* add the mappings */
+               MAKE_STD_ZVAL(tmp);
+               ZVAL_STRINGL(tmp, name, namelen, 1);
+               zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL);
+
+               MAKE_STD_ZVAL(tmp);
+               ZVAL_LONG(tmp, pid);
+               zend_hash_update(disp->name_to_dispid, name, namelen+1, (void*)&tmp, sizeof(zval *), NULL);
+       }
+}
+
+static php_dispatchex *disp_constructor(zval *object TSRMLS_DC)
+{
+       php_dispatchex *disp = (php_dispatchex*)CoTaskMemAlloc(sizeof(php_dispatchex));
+
+       trace("constructing a COM proxy\n");
+       
+       if (disp == NULL)
+               return NULL;
+
+       memset(disp, 0, sizeof(php_dispatchex));
+
+       disp->engine_thread = tsrm_thread_id();
+       disp->lpVtbl = &php_dispatch_vtbl;
+       disp->refcount = 1;
+
+
+       if (object)
+               ZVAL_ADDREF(object);
+       disp->object = object;
+
+       disp->id = zend_list_insert(disp, le_dispatch);
+       
+       return disp;
+}
+
+static void disp_destructor(php_dispatchex *disp)
+{
+       TSRMLS_FETCH();
+       
+       trace("destroying COM wrapper for PHP object %s\n", Z_OBJCE_P(disp->object)->name);
+
+       disp->id = 0;
+       
+       if (disp->refcount > 0)
+               CoDisconnectObject((IUnknown*)disp, 0);
+
+       zend_hash_destroy(disp->dispid_to_name);
+       zend_hash_destroy(disp->name_to_dispid);
+       FREE_HASHTABLE(disp->dispid_to_name);
+       FREE_HASHTABLE(disp->name_to_dispid);
+                       
+       if (disp->object)
+               zval_ptr_dtor(&disp->object);
+
+
+       CoTaskMemFree(disp);
+}
+
+PHPAPI IDispatch *php_COM_export_as_sink(zval *val, GUID *sinkid, HashTable *id_to_name TSRMLS_DC)
+{
+       php_dispatchex *disp = disp_constructor(val TSRMLS_CC);
+       HashPosition pos;
+       char *name = NULL;
+       zval *tmp, **ntmp;
+       int namelen;
+       int keytype;
+       ulong pid;
+
+       disp->dispid_to_name = id_to_name;
+
+       memcpy(&disp->sinkid, sinkid, sizeof(disp->sinkid));
+       
+       /* build up the reverse mapping */
+       ALLOC_HASHTABLE(disp->name_to_dispid);
+       zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
+       
+       zend_hash_internal_pointer_reset_ex(id_to_name, &pos);
+       while (HASH_KEY_NON_EXISTANT != (keytype =
+                               zend_hash_get_current_key_ex(id_to_name, &name, &namelen, &pid, 0, &pos))) {
+
+               if (keytype == HASH_KEY_IS_LONG) {
+
+                       zend_hash_get_current_data_ex(id_to_name, (void**)&ntmp, &pos);
+                       
+                       MAKE_STD_ZVAL(tmp);
+                       ZVAL_LONG(tmp, pid);
+                       zend_hash_update(disp->name_to_dispid, Z_STRVAL_PP(ntmp), Z_STRLEN_PP(ntmp)+1, (void*)&tmp, sizeof(zval *), NULL);
+               }
+
+               zend_hash_move_forward_ex(id_to_name, &pos);
+       }
+
+       return (IDispatch*)disp;
+}
+
+PHPAPI IDispatch *php_COM_export_object(zval *val TSRMLS_DC)
+{
+       php_dispatchex *disp = NULL;
+
+       if (Z_TYPE_P(val) != IS_OBJECT)
+               return NULL;
+
+       if (Z_OBJCE_P(val) == &COM_class_entry || !strcmp(Z_OBJCE_P(val)->name, "COM")) {
+               /* pass back it's IDispatch directly */
+               zval **tmp;
+               comval *obj;
+               int type;
+               
+               zend_hash_index_find(Z_OBJPROP_P(val), 0, (void**)&tmp);
+               obj = (comval *)zend_list_find(Z_LVAL_PP(tmp), &type);
+               if (type != IS_COM)
+                       return NULL;
+
+               C_DISPATCH(obj)->lpVtbl->AddRef(C_DISPATCH(obj));
+               return C_DISPATCH(obj);
+       }
+
+       disp = disp_constructor(val TSRMLS_CC);
+       generate_dispids(disp TSRMLS_CC);
+
+       return (IDispatch*)disp;
+}
+
+
diff --git a/ext/mysql/mysql.mak b/ext/mysql/mysql.mak
new file mode 100644 (file)
index 0000000..8dd34ec
--- /dev/null
@@ -0,0 +1,168 @@
+# Temporarily here -- later may go into some batch file
+# which will set this as an environment variable
+PROJECT_ROOT = ..\..
+
+# Module details
+MODULE_NAME = phpmysql
+MODULE_DESC = "PHP MySQL Extension"
+VMAJ = 0
+VMIN = 60
+VREV = 0
+
+#include the common settings
+include $(PROJECT_ROOT)/netware/common.mif
+
+# MYSQL stuff
+MYSQL_DIR = P:/APPS/script/sw/mysql
+
+# Build type defaults to 'release'
+ifndef BUILD
+BUILD = release
+endif
+
+# Extensions of all input and output files
+.SUFFIXES:
+.SUFFIXES: .nlm .lib .obj .cpp .c .msg .mlc .mdb .xdc .d
+
+# Source files
+C_SRC = php_mysql.c \
+        start.c 
+
+CPP_SRC_NODIR = $(notdir $(CPP_SRC))
+C_SRC_NODIR = $(notdir $(C_SRC))
+SRC_DIR = $(dir $(CPP_SRC) $(C_SRC))
+
+# Library files
+LIBRARY = $(MYSQL_DIR)/lib/libmysqlclient.lib
+
+# Destination directories and files
+OBJ_DIR = $(BUILD)
+FINAL_DIR = $(BUILD)
+OBJECTS  = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.obj) $(C_SRC_NODIR:.c=.obj))
+DEPDS  = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.d) $(C_SRC_NODIR:.c=.d))
+
+# Binary file
+ifndef BINARY
+       BINARY=$(FINAL_DIR)\$(MODULE_NAME).nlm
+endif
+
+# Compile flags
+C_FLAGS  = -c -maxerrors 25 -msgstyle gcc -wchar_t on -bool on -processor Pentium -align 1
+C_FLAGS += -nostdinc -nosyspath  
+C_FLAGS += -DNETWARE -DZTS -DNEW_LIBC -DUSE_OLD_FUNCTIONS -DCOMPILE_DL=1
+C_FLAGS += -I. -I$(PROJECT_ROOT)/main -I$(PROJECT_ROOT)/ext/standard -I$(PROJECT_ROOT) -I$(PROJECT_ROOT)/netware
+C_FLAGS += -I$(PROJECT_ROOT)/zend -I$(PROJECT_ROOT)/tsrm
+C_FLAGS += -I- -I$(SDK_DIR)/include -I$(MWCIncludes)
+C_FLAGS += -I$(MYSQL_DIR)/include -DCOMPILE_DL_MYSQL=1
+C_FLAGS += -I$(WINSOCK_DIR)/include/nlm -I$(WINSOCK_DIR)/include
+
+
+# Extra stuff based on debug / release builds
+ifeq '$(BUILD)' 'debug'
+       SYM_FILE = $(FINAL_DIR)\$(MODULE_NAME).sym
+       C_FLAGS  += -inline smart -sym on -sym codeview4 -opt off -opt intrinsics -DDEBUGGING -DDKFBPON
+       C_FLAGS += -exc cw -DZEND_DEBUG=1
+       LD_FLAGS += -sym on -sym codeview4 -osym $(SYM_FILE)
+       export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtld.lib
+else
+       C_FLAGS  += -opt speed -inline on -inline smart -inline auto -sym off -opt intrinsics
+       C_FLAGS += -opt level=4 -DZEND_DEBUG=0
+       LD_FLAGS += -sym off
+       export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtl.lib
+endif
+
+
+# Dependencies
+MODULE = LibC    \
+         phplib
+IMPORT = @$(SDK_DIR)/imports/libc.imp        \
+         @$(SDK_DIR)/imports/ws2nlm.imp      \
+         @$(MPK_DIR)/import/mpkOrg.imp       \
+         @$(PROJECT_ROOT)/netware/phplib.imp
+
+#EXPORT = mysql_functions    \
+#         mysql_module_entry \
+#         ($(MODULE_NAME).nlm) get_module
+EXPORT = ($(MODULE_NAME)) get_module
+API = OutputToScreen
+
+# Virtual paths
+vpath %.cpp .
+vpath %.c . ..\..\netware
+vpath %.obj $(OBJ_DIR)
+
+
+all: prebuild project
+
+.PHONY: all
+
+prebuild:
+       @if not exist $(OBJ_DIR) md $(OBJ_DIR)
+
+project: $(BINARY)
+       @echo Build complete.
+
+$(OBJ_DIR)/%.d: %.cpp
+       @echo Building Dependencies for $(<F)
+       @$(CC) -M $< $(C_FLAGS) -o $@
+
+$(OBJ_DIR)/%.d: %.c
+       @echo Building Dependencies for $(<F)
+       @$(CC) -M $< $(C_FLAGS) -o $@
+
+$(OBJ_DIR)/%.obj: %.cpp
+       @echo Compiling $?...
+       @$(CC) $< $(C_FLAGS) -o $@
+       
+$(OBJ_DIR)/%.obj: %.c
+       @echo Compiling $?...
+       @$(CC) $< $(C_FLAGS) -o $@
+
+
+$(BINARY): $(DEPDS) $(OBJECTS)
+       @echo Import $(IMPORT) > $(basename $@).def
+ifdef API
+       @echo Import $(API) >> $(basename $@).def
+endif
+       @echo Module $(MODULE) >> $(basename $@).def
+ifdef EXPORT
+       @echo Export $(EXPORT) >> $(basename $@).def
+endif
+       @echo AutoUnload >> $(basename $@).def
+ifeq '$(BUILD)' 'debug'
+       @echo Debug >> $(basename $@).def
+endif
+       @echo Flag_On 0x00000008 >> $(basename $@).def
+       @echo Start _NonAppStart >> $(basename $@).def
+       @echo Exit _NonAppStop >> $(basename $@).def
+
+       @echo Linking $@...
+       @echo $(LD_FLAGS) -commandfile $(basename $@).def > $(basename $@).link
+       @echo $(LIBRARY) $(OBJECTS) >> $(basename $@).link
+       @$(LINK) @$(basename $@).link
+
+
+.PHONY: clean
+clean: cleand cleanobj cleanbin
+
+.PHONY: cleand
+cleand:
+       @echo Deleting all dependency files...
+       -@del "$(OBJ_DIR)\*.d"
+
+.PHONY: cleanobj
+cleanobj:
+       @echo Deleting all object files...
+       -@del "$(OBJ_DIR)\*.obj"
+
+.PHONY: cleanbin
+cleanbin:
+       @echo Deleting binary files...
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).nlm"
+       @echo Deleting MAP, DEF files, etc....
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).map"
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).def"
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).link"
+ifeq '$(BUILD)' 'debug'
+       -@del $(FINAL_DIR)\$(MODULE_NAME).sym
+endif
diff --git a/ext/rpc/com/dispatch.c b/ext/rpc/com/dispatch.c
new file mode 100644 (file)
index 0000000..23c3b0d
--- /dev/null
@@ -0,0 +1,627 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 4                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2002 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 2.02 of the PHP license,      |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available at through the world-wide-web at                           |
+   | http://www.php.net/license/2_02.txt.                                 |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | license@php.net so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Wez Furlong <wez@thebrainroom.com>                           |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/* 
+ * This module is used to export PHP objects to COM and DOTNET by exposing
+ * them as objects implementing IDispatch.
+ * */
+
+#include "php.h"
+#include "php_COM.h"
+#include "php_VARIANT.h"
+#include "conversion.h"
+#include "variant.h"
+
+#define COBJMACROS
+#include <unknwn.h> /* IDispatch */
+#include <dispex.h> /* IDispatchEx */
+
+
+typedef struct {
+       /* This first part MUST match the declaration
+        * of interface IDispatchEx */
+       CONST_VTBL struct IDispatchExVtbl *lpVtbl;
+
+       /* now the PHP stuff */
+       
+       THREAD_T engine_thread; /* for sanity checking */
+       zval *object;                   /* the object exported */
+       LONG refcount;                  /* COM reference count */
+
+       HashTable *dispid_to_name;      /* keep track of dispid -> name mappings */
+       HashTable *name_to_dispid;      /* keep track of name -> dispid mappings */
+
+       GUID sinkid;    /* iid that we "implement" for event sinking */
+       
+       int id;
+} php_dispatchex;
+
+static void disp_destructor(php_dispatchex *disp);
+
+static void dispatch_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+       php_dispatchex *disp = (php_dispatchex *)rsrc->ptr;
+       disp_destructor(disp);
+}
+
+static int le_dispatch;
+int php_COM_dispatch_init(int module_number TSRMLS_DC)
+{
+       le_dispatch = zend_register_list_destructors_ex(dispatch_dtor, NULL, "COM:Dispatch", module_number);
+       return le_dispatch;
+}
+
+
+/* {{{ trace */
+static inline void trace(char *fmt, ...)
+{
+       va_list ap;
+       char buf[4096];
+
+       sprintf(buf, "T=%08x ", tsrm_thread_id());
+       OutputDebugString(buf);
+       
+       va_start(ap, fmt);
+       vsnprintf(buf, sizeof(buf), fmt, ap);
+
+       OutputDebugString(buf);
+       
+       va_end(ap);
+}
+/* }}} */
+
+#define FETCH_DISP(methname)   \
+       php_dispatchex *disp = (php_dispatchex*)This; \
+       trace(" PHP:%s %s\n", Z_OBJCE_P(disp->object)->name, methname); \
+       if (tsrm_thread_id() != disp->engine_thread) \
+               return E_UNEXPECTED;
+
+
+static HRESULT STDMETHODCALLTYPE disp_queryinterface( 
+       IDispatchEx *This,
+       /* [in] */ REFIID riid,
+       /* [iid_is][out] */ void **ppvObject)
+{
+       FETCH_DISP("QueryInterface");
+
+       if (IsEqualGUID(&IID_IUnknown, riid) ||
+                       IsEqualGUID(&IID_IDispatch, riid) ||
+                       IsEqualGUID(&IID_IDispatchEx, riid) ||
+                       IsEqualGUID(&disp->sinkid, riid)) {
+               *ppvObject = This;
+               InterlockedIncrement(&disp->refcount);
+               return S_OK;
+       }
+
+       *ppvObject = NULL;
+       return E_NOINTERFACE;
+}
+        
+static ULONG STDMETHODCALLTYPE disp_addref(IDispatchEx *This)
+{
+       FETCH_DISP("AddRef");
+
+       return InterlockedIncrement(&disp->refcount);
+}
+        
+static ULONG STDMETHODCALLTYPE disp_release(IDispatchEx *This)
+{
+       ULONG ret;
+       TSRMLS_FETCH();
+       FETCH_DISP("Release");
+
+       ret = InterlockedDecrement(&disp->refcount);
+       trace("-- refcount now %d\n", ret);
+       if (ret == 0) {
+               /* destroy it */
+               if (disp->id)
+                       zend_list_delete(disp->id);
+       }
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_gettypeinfocount( 
+       IDispatchEx *This,
+       /* [out] */ UINT *pctinfo)
+{
+       FETCH_DISP("GetTypeInfoCount");
+
+       *pctinfo = 0;
+       return S_OK;
+}
+        
+static HRESULT STDMETHODCALLTYPE disp_gettypeinfo( 
+       IDispatchEx *This,
+       /* [in] */ UINT iTInfo,
+       /* [in] */ LCID lcid,
+       /* [out] */ ITypeInfo **ppTInfo)
+{
+       FETCH_DISP("GetTypeInfo");
+       
+       *ppTInfo = NULL;
+       return DISP_E_BADINDEX;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getidsofnames( 
+       IDispatchEx *This,
+       /* [in] */ REFIID riid,
+       /* [size_is][in] */ LPOLESTR *rgszNames,
+       /* [in] */ UINT cNames,
+       /* [in] */ LCID lcid,
+       /* [size_is][out] */ DISPID *rgDispId)
+{
+       UINT i;
+       HRESULT ret = S_OK;
+       TSRMLS_FETCH();
+       FETCH_DISP("GetIDsOfNames");
+
+       for (i = 0; i < cNames; i++) {
+               char *name;
+               unsigned int namelen;
+               zval **tmp;
+               
+               name = php_OLECHAR_to_char(rgszNames[i], &namelen, CP_ACP TSRMLS_CC);
+               
+               /* Lookup the name in the hash */
+               if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == FAILURE) {
+                       ret = DISP_E_UNKNOWNNAME;
+                       rgDispId[i] = 0;
+               } else {
+                       rgDispId[i] = Z_LVAL_PP(tmp);
+               }
+
+               efree(name);
+
+       }
+       
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_invoke( 
+       IDispatchEx *This,
+       /* [in] */ DISPID dispIdMember,
+       /* [in] */ REFIID riid,
+       /* [in] */ LCID lcid,
+       /* [in] */ WORD wFlags,
+       /* [out][in] */ DISPPARAMS *pDispParams,
+       /* [out] */ VARIANT *pVarResult,
+       /* [out] */ EXCEPINFO *pExcepInfo,
+       /* [out] */ UINT *puArgErr)
+{
+       return This->lpVtbl->InvokeEx(This, dispIdMember,
+                       lcid, wFlags, pDispParams,
+                       pVarResult, pExcepInfo, NULL);
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getdispid( 
+       IDispatchEx *This,
+       /* [in] */ BSTR bstrName,
+       /* [in] */ DWORD grfdex,
+       /* [out] */ DISPID *pid)
+{
+       HRESULT ret = DISP_E_UNKNOWNNAME;
+       char *name;
+       unsigned int namelen;
+       zval **tmp;
+       TSRMLS_FETCH();
+       FETCH_DISP("GetDispID");
+
+       name = php_OLECHAR_to_char(bstrName, &namelen, CP_ACP TSRMLS_CC);
+
+       /* Lookup the name in the hash */
+       if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS) {
+               *pid = Z_LVAL_PP(tmp);
+               ret = S_OK;
+       }
+
+       efree(name);
+       
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_invokeex( 
+       IDispatchEx *This,
+       /* [in] */ DISPID id,
+       /* [in] */ LCID lcid,
+       /* [in] */ WORD wFlags,
+       /* [in] */ DISPPARAMS *pdp,
+       /* [out] */ VARIANT *pvarRes,
+       /* [out] */ EXCEPINFO *pei,
+       /* [unique][in] */ IServiceProvider *pspCaller)
+{
+       zval **name;
+       UINT i;
+       int codepage = CP_ACP;
+       zval *retval = NULL;
+       zval ***params = NULL;
+       HRESULT ret = DISP_E_MEMBERNOTFOUND;
+       TSRMLS_FETCH();
+       FETCH_DISP("InvokeEx");
+
+       if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) {
+               /* TODO: add support for overloaded objects */
+
+               trace("-- Invoke: %d %20s flags=%08x args=%d\n", id, Z_STRVAL_PP(name), wFlags, pdp->cArgs);
+               
+               /* convert args into zvals.
+                * Args are in reverse order */
+               params = (zval ***)emalloc(sizeof(zval **) * pdp->cArgs);
+               for (i = 0; i < pdp->cArgs; i++) {
+                       VARIANT *arg;
+                       zval *zarg;
+                       
+                       arg = &pdp->rgvarg[ pdp->cArgs - 1 - i];
+
+                       trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg));
+
+                       ALLOC_INIT_ZVAL(zarg);
+                       
+                       if (V_VT(arg) == VT_DISPATCH) {
+                               trace("arg %d is dispatchable\n", i);
+                               if (NULL == php_COM_object_from_dispatch(V_DISPATCH(arg), zarg TSRMLS_CC)) {
+                                       trace("failed to convert arg %d to zval\n", i);
+                                       ZVAL_NULL(zarg);
+                               }
+                       } else {
+                               // arg can't be an idispatch, so we don't care for the implicit AddRef() call here
+                               if (FAILURE == php_variant_to_pval(arg, zarg, codepage TSRMLS_CC)) {
+                                       trace("failed to convert arg %d to zval\n", i);
+                                       ZVAL_NULL(zarg);
+                               }
+                       }
+                       
+                       params[i] = &zarg;
+               }
+
+               trace("arguments processed, prepare to do some work\n");        
+               
+               if (wFlags & DISPATCH_PROPERTYGET) {
+                       trace("trying to get a property\n");
+                       zend_hash_find(Z_OBJPROP_P(disp->object), Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, (void**)&retval);
+               } else if (wFlags & DISPATCH_PROPERTYPUT) {
+                       trace("trying to set a property\n");
+                       add_property_zval(disp->object, Z_STRVAL_PP(name), *params[0]);
+               } else if (wFlags & DISPATCH_METHOD) {
+                       trace("Trying to call user function\n");
+                       if (SUCCESS == call_user_function_ex(EG(function_table), &disp->object, *name,
+                                       &retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) {
+                               ret = S_OK;
+                       } else {
+                               ret = DISP_E_EXCEPTION;
+                       }
+               } else {
+                       trace("Don't know how to handle this invocation %08x\n", wFlags);
+               }
+       
+               /* release arguments */
+               for (i = 0; i < pdp->cArgs; i++)
+                       zval_ptr_dtor(params[i]);
+               efree(params);
+               
+               /* return value */
+               if (retval) {
+                       if (pvarRes) {
+                               if (Z_TYPE_P(retval) == IS_OBJECT) {
+                                       /* export the object using a dispatch like ourselves */
+                                       VariantInit(pvarRes);
+                                       V_VT(pvarRes) = VT_DISPATCH;
+                                       V_DISPATCH(pvarRes) = php_COM_export_object(retval TSRMLS_CC);
+                               } else {
+                                       php_pval_to_variant(retval, pvarRes, codepage TSRMLS_CC);
+                               }
+                       }
+                       zval_ptr_dtor(&retval);
+               } else if (pvarRes) {
+                       VariantInit(pvarRes);
+               }
+               
+       } else {
+               trace("InvokeEx: I don't support DISPID=%d\n", id);
+       }
+
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_deletememberbyname( 
+       IDispatchEx *This,
+       /* [in] */ BSTR bstrName,
+       /* [in] */ DWORD grfdex)
+{
+       FETCH_DISP("DeleteMemberByName");
+
+       return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_deletememberbydispid( 
+       IDispatchEx *This,
+       /* [in] */ DISPID id)
+{
+       FETCH_DISP("DeleteMemberByDispID");
+       
+       return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getmemberproperties( 
+       IDispatchEx *This,
+       /* [in] */ DISPID id,
+       /* [in] */ DWORD grfdexFetch,
+       /* [out] */ DWORD *pgrfdex)
+{
+       FETCH_DISP("GetMemberProperties");
+
+       return DISP_E_UNKNOWNNAME;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getmembername( 
+       IDispatchEx *This,
+       /* [in] */ DISPID id,
+       /* [out] */ BSTR *pbstrName)
+{
+       zval *name;
+       TSRMLS_FETCH();
+       FETCH_DISP("GetMemberName");
+
+       if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) {
+               OLECHAR *olestr = php_char_to_OLECHAR(Z_STRVAL_P(name), Z_STRLEN_P(name), CP_ACP TSRMLS_CC);
+               *pbstrName = SysAllocString(olestr);
+               efree(olestr);
+               return S_OK;
+       } else {
+               return DISP_E_UNKNOWNNAME;
+       }
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getnextdispid( 
+       IDispatchEx *This,
+       /* [in] */ DWORD grfdex,
+       /* [in] */ DISPID id,
+       /* [out] */ DISPID *pid)
+{
+       ulong next = id+1;
+       FETCH_DISP("GetNextDispID");
+
+       while(!zend_hash_index_exists(disp->dispid_to_name, next))
+               next++;
+
+       if (zend_hash_index_exists(disp->dispid_to_name, next)) {
+               *pid = next;
+               return S_OK;
+       }
+       return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE disp_getnamespaceparent( 
+       IDispatchEx *This,
+       /* [out] */ IUnknown **ppunk)
+{
+       FETCH_DISP("GetNameSpaceParent");
+
+       *ppunk = NULL;
+       return E_NOTIMPL;
+}
+        
+static struct IDispatchExVtbl php_dispatch_vtbl = {
+       disp_queryinterface,
+       disp_addref,
+       disp_release,
+       disp_gettypeinfocount,
+       disp_gettypeinfo,
+       disp_getidsofnames,
+       disp_invoke,
+       disp_getdispid,
+       disp_invokeex,
+       disp_deletememberbyname,
+       disp_deletememberbydispid,
+       disp_getmemberproperties,
+       disp_getmembername,
+       disp_getnextdispid,
+       disp_getnamespaceparent
+};
+
+
+/* enumerate functions and properties of the object and assign
+ * dispatch ids */
+static void generate_dispids(php_dispatchex *disp TSRMLS_DC)
+{
+       HashPosition pos;
+       char *name = NULL;
+       zval *tmp;
+       int namelen;
+       int keytype;
+       ulong pid;
+
+       if (disp->dispid_to_name == NULL) {
+               ALLOC_HASHTABLE(disp->dispid_to_name);
+               ALLOC_HASHTABLE(disp->name_to_dispid);
+               zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
+               zend_hash_init(disp->dispid_to_name, 0, NULL, ZVAL_PTR_DTOR, 0);
+       }
+
+       /* properties */
+       zend_hash_internal_pointer_reset_ex(Z_OBJPROP_PP(&disp->object), &pos);
+       while (HASH_KEY_NON_EXISTANT != (keytype =
+                               zend_hash_get_current_key_ex(Z_OBJPROP_PP(&disp->object), &name, &namelen, &pid, 0, &pos))) {
+               char namebuf[32];
+               if (keytype == HASH_KEY_IS_LONG) {
+                       sprintf(namebuf, "%d", pid);
+                       name = namebuf;
+                       namelen = strlen(namebuf);
+               }
+
+               zend_hash_move_forward_ex(Z_OBJPROP_PP(&disp->object), &pos);
+               
+               /* Find the existing id */
+               if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS)
+                       continue;
+               
+               /* add the mappings */
+               MAKE_STD_ZVAL(tmp);
+               ZVAL_STRINGL(tmp, name, namelen, 1);
+               zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL);
+
+               MAKE_STD_ZVAL(tmp);
+               ZVAL_LONG(tmp, pid);
+               zend_hash_update(disp->name_to_dispid, name, namelen+1, (void*)&tmp, sizeof(zval *), NULL);
+
+       }
+       
+       /* functions */
+       zend_hash_internal_pointer_reset_ex(&Z_OBJCE_PP(&disp->object)->function_table, &pos);
+       while (HASH_KEY_NON_EXISTANT != (keytype =
+                               zend_hash_get_current_key_ex(&Z_OBJCE_PP(&disp->object)->function_table, &name, &namelen, &pid, 0, &pos))) {
+
+               char namebuf[32];
+               if (keytype == HASH_KEY_IS_LONG) {
+                       sprintf(namebuf, "%d", pid);
+                       name = namebuf;
+                       namelen = strlen(namebuf);
+               }
+
+               zend_hash_move_forward_ex(Z_OBJPROP_PP(&disp->object), &pos);
+               
+               /* Find the existing id */
+               if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS)
+                       continue;
+               
+               /* add the mappings */
+               MAKE_STD_ZVAL(tmp);
+               ZVAL_STRINGL(tmp, name, namelen, 1);
+               zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL);
+
+               MAKE_STD_ZVAL(tmp);
+               ZVAL_LONG(tmp, pid);
+               zend_hash_update(disp->name_to_dispid, name, namelen+1, (void*)&tmp, sizeof(zval *), NULL);
+       }
+}
+
+static php_dispatchex *disp_constructor(zval *object TSRMLS_DC)
+{
+       php_dispatchex *disp = (php_dispatchex*)CoTaskMemAlloc(sizeof(php_dispatchex));
+
+       trace("constructing a COM proxy\n");
+       
+       if (disp == NULL)
+               return NULL;
+
+       memset(disp, 0, sizeof(php_dispatchex));
+
+       disp->engine_thread = tsrm_thread_id();
+       disp->lpVtbl = &php_dispatch_vtbl;
+       disp->refcount = 1;
+
+
+       if (object)
+               ZVAL_ADDREF(object);
+       disp->object = object;
+
+       disp->id = zend_list_insert(disp, le_dispatch);
+       
+       return disp;
+}
+
+static void disp_destructor(php_dispatchex *disp)
+{
+       TSRMLS_FETCH();
+       
+       trace("destroying COM wrapper for PHP object %s\n", Z_OBJCE_P(disp->object)->name);
+
+       disp->id = 0;
+       
+       if (disp->refcount > 0)
+               CoDisconnectObject((IUnknown*)disp, 0);
+
+       zend_hash_destroy(disp->dispid_to_name);
+       zend_hash_destroy(disp->name_to_dispid);
+       FREE_HASHTABLE(disp->dispid_to_name);
+       FREE_HASHTABLE(disp->name_to_dispid);
+                       
+       if (disp->object)
+               zval_ptr_dtor(&disp->object);
+
+
+       CoTaskMemFree(disp);
+}
+
+PHPAPI IDispatch *php_COM_export_as_sink(zval *val, GUID *sinkid, HashTable *id_to_name TSRMLS_DC)
+{
+       php_dispatchex *disp = disp_constructor(val TSRMLS_CC);
+       HashPosition pos;
+       char *name = NULL;
+       zval *tmp, **ntmp;
+       int namelen;
+       int keytype;
+       ulong pid;
+
+       disp->dispid_to_name = id_to_name;
+
+       memcpy(&disp->sinkid, sinkid, sizeof(disp->sinkid));
+       
+       /* build up the reverse mapping */
+       ALLOC_HASHTABLE(disp->name_to_dispid);
+       zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
+       
+       zend_hash_internal_pointer_reset_ex(id_to_name, &pos);
+       while (HASH_KEY_NON_EXISTANT != (keytype =
+                               zend_hash_get_current_key_ex(id_to_name, &name, &namelen, &pid, 0, &pos))) {
+
+               if (keytype == HASH_KEY_IS_LONG) {
+
+                       zend_hash_get_current_data_ex(id_to_name, (void**)&ntmp, &pos);
+                       
+                       MAKE_STD_ZVAL(tmp);
+                       ZVAL_LONG(tmp, pid);
+                       zend_hash_update(disp->name_to_dispid, Z_STRVAL_PP(ntmp), Z_STRLEN_PP(ntmp)+1, (void*)&tmp, sizeof(zval *), NULL);
+               }
+
+               zend_hash_move_forward_ex(id_to_name, &pos);
+       }
+
+       return (IDispatch*)disp;
+}
+
+PHPAPI IDispatch *php_COM_export_object(zval *val TSRMLS_DC)
+{
+       php_dispatchex *disp = NULL;
+
+       if (Z_TYPE_P(val) != IS_OBJECT)
+               return NULL;
+
+       if (Z_OBJCE_P(val) == &COM_class_entry || !strcmp(Z_OBJCE_P(val)->name, "COM")) {
+               /* pass back it's IDispatch directly */
+               zval **tmp;
+               comval *obj;
+               int type;
+               
+               zend_hash_index_find(Z_OBJPROP_P(val), 0, (void**)&tmp);
+               obj = (comval *)zend_list_find(Z_LVAL_PP(tmp), &type);
+               if (type != IS_COM)
+                       return NULL;
+
+               C_DISPATCH(obj)->lpVtbl->AddRef(C_DISPATCH(obj));
+               return C_DISPATCH(obj);
+       }
+
+       disp = disp_constructor(val TSRMLS_CC);
+       generate_dispids(disp TSRMLS_CC);
+
+       return (IDispatch*)disp;
+}
+
+
diff --git a/ext/standard/tests/file/002.phpt b/ext/standard/tests/file/002.phpt
new file mode 100644 (file)
index 0000000..4642bac
--- /dev/null
@@ -0,0 +1,54 @@
+--TEST--
+File/Stream functions
+--POST--
+--GET--
+--FILE--
+<?php
+
+$data = <<<EOD
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+EOD;
+
+$name = tempnam("./ext/standard/tests/file/", "php");
+$fp = fopen($name, "w");
+fwrite($fp, $data);
+fclose($fp);
+
+//readfile($name);
+echo file_get_contents($name);
+
+unlink($name);
+
+?>
+--EXPECT--
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
+blah blah blah blah blah blah blah
diff --git a/main/config.nw.h b/main/config.nw.h
new file mode 100644 (file)
index 0000000..b2c15b5
--- /dev/null
@@ -0,0 +1,274 @@
+/* config.nw.h.  Configure file for NetWare platform */
+
+
+/****
+
+Need to carefully look into each constant and either define or undef it w.r.t. NetWare.
+
+****/
+
+
+/* Define if PHP to setup it's own SIGCHLD handler (not needed on NetWare) */
+#define PHP_SIGCHILD 0
+
+/* dns functions found in resolv.lib */
+#define HAVE_LIBBIND 1
+
+#define HAVE_GETSERVBYNAME 1
+#define HAVE_GETSERVBYPORT 1
+#define HAVE_GETPROTOBYNAME 1
+#define HAVE_GETPROTOBYNUMBER 1
+
+/* set to enable bcmath */
+#define WITH_BCMATH 1
+
+/* set to enable mysql */
+#define HAVE_MYSQL 1
+
+/* set to enable FTP support */
+#define HAVE_FTP 1
+
+/* set to enable bundled PCRE library */
+#define HAVE_BUNDLED_PCRE      1
+
+/* set to enable bundled expat library */
+/* #define HAVE_LIBEXPAT 1 */ /* For now */
+#define HAVE_WDDX 0
+
+/* set to enable the crypt command */
+/* #define HAVE_CRYPT 1 */
+/* #define HAVE_CRYPT_H 1 */
+
+/* set to enable force cgi redirect */
+#define FORCE_CGI_REDIRECT 0
+
+/* should be added to runtime config*/
+#define PHP_URL_FOPEN 1
+
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+/* ----------------------------------------------------------------
+   The following are defaults for run-time configuration
+   ---------------------------------------------------------------*/
+
+#define PHP_SAFE_MODE 0
+#define MAGIC_QUOTES 0
+/* This is the default configuration file to read */
+#define CONFIGURATION_FILE_PATH "php.ini"
+#define USE_CONFIG_FILE 1
+
+#define PHP_INCLUDE_PATH       NULL
+
+
+/* Undefine if you want stricter XML/SGML compliance by default */
+/* this disables "<?expression?>" and "<?=expression?>" */
+#define DEFAULT_SHORT_OPEN_TAG "1"
+
+
+/* ----------------------------------------------------------------
+   The following defines are for those modules which require
+   external libraries to compile.  These will be removed from 
+   here in a future beta, as these modules will be moved out to dll's 
+   ---------------------------------------------------------------*/
+#define HAVE_ERRMSG_H 0 /*needed for mysql 3.21.17 and up*/
+#undef HAVE_ADABAS
+#undef HAVE_SOLID
+
+
+/* ----------------------------------------------------------------
+   The following may or may not be (or need to be) ported to the
+   windows environment.
+   ---------------------------------------------------------------*/
+
+/* Define if you have the link function.  */
+#undef HAVE_LINK
+
+/* Define if you have the symlink function.  */
+#undef HAVE_SYMLINK
+
+/* Define if you have the usleep function.  */
+#undef HAVE_USLEEP
+
+#define HAVE_GETCWD 1
+/* #define HAVE_POSIX_READDIR_R 1 */  /* We will use readdir() from LibC */
+
+#define NEED_ISBLANK 1
+
+/* ----------------------------------------------------------------
+   The following should never need to be played with
+   Functions defined to 0 or remarked out are either already
+   handled by the standard VC libraries, or are no longer needed, or
+   simply will/can not be ported.
+
+   DONT TOUCH!!!!!  Unless you realy know what your messing with!
+   ---------------------------------------------------------------*/
+
+#define DISCARD_PATH 0
+#undef HAVE_SETITIMER
+#undef HAVE_IODBC
+#define HAVE_UODBC 1
+#define HAVE_LIBDL 1
+#define HAVE_SENDMAIL 1
+#define HAVE_GETTIMEOFDAY 1
+#define HAVE_PUTENV 1
+#define HAVE_LIMITS_H 1
+
+#define HAVE_TZSET 1
+#define HAVE_TZNAME 1
+
+/* Define if you have the flock function.  */
+#undef HAVE_FLOCK
+
+/* Define if you have alloca, as a function or macro.  */
+/* Though we have alloca(), this seems to be causing some problem with the stack pointer -- hence not using it */
+/* #define HAVE_ALLOCA 1 */
+
+/* Define if you have <sys/time.h> */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have <signal.h> */
+#define HAVE_SIGNAL_H 1
+
+/* Define if your struct stat has st_blksize.  */
+#define HAVE_ST_BLKSIZE
+
+/* Define if your struct stat has st_blocks.  */
+#define HAVE_ST_BLOCKS
+
+/* Define if your struct stat has st_rdev.  */
+#define HAVE_ST_RDEV 1
+
+/* Define if utime(file, NULL) sets file's timestamp to the present.  */
+#define HAVE_UTIME_NULL 1
+
+/* Define if you have the vprintf function.  */
+#define HAVE_VPRINTF 1
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define both of these if you want the bundled REGEX library */
+#define REGEX 1
+#define HSREGEX 1
+
+#define HAVE_PCRE 1
+
+#define HAVE_LDAP 1
+
+/* Define if you have the gcvt function.  */
+/* #define HAVE_GCVT 1 */
+
+/* Define if you have the getlogin function.  */
+/* #define HAVE_GETLOGIN 1 */
+
+/* Define if you have the gettimeofday function.  */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memmove function.  */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the putenv function.  */
+/* #define HAVE_PUTENV 1 */   /* Why are such things defined in more than one place ? */
+
+/* Define if you have the regcomp function.  */
+/* #define HAVE_REGCOMP 1 */
+
+/* Define if you have the setlocale function.  */
+/* #define HAVE_SETLOCALE 1 */    /* LibC doesn't seem to be supporting fully -- hence commenting for now */
+
+#define HAVE_LOCALECONV 1
+
+#define HAVE_LOCALE_H 1
+
+/* Define if you have the setvbuf function.  */
+#ifndef HAVE_LIBBIND
+#define HAVE_SETVBUF 1
+#endif
+
+/* Define if you have the snprintf function.  */
+#define HAVE_SNPRINTF 1
+#define HAVE_VSNPRINTF 1
+/* Define if you have the strcasecmp function.  */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the strdup function.  */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strerror function.  */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strstr function.  */
+#define HAVE_STRSTR 1
+
+/* Define if you have the tempnam function.  */
+#define HAVE_TEMPNAM 1
+
+/* Define if you have the utime function.  */
+#define HAVE_UTIME 1
+
+/* Define if you have the <dirent.h> header file.  */
+#define HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file.  */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <grp.h> header file.  */
+#define HAVE_GRP_H 0
+
+/* Define if you have the <pwd.h> header file.  */
+#define HAVE_PWD_H 1
+
+/* Define if you have the <string.h> header file.  */
+#define HAVE_STRING_H 1
+
+/* Define if you have the <sys/file.h> header file.  */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/socket.h> header file.  */
+#define HAVE_SYS_SOCKET_H 1 /* Added '1' for '#if' to work */
+
+/* Define if you have the <sys/wait.h> header file.  */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have the <syslog.h> header file.  */
+/* #define HAVE_SYSLOG_H 1 */
+
+/* Define if you have the <unistd.h> header file.  */
+#define HAVE_UNISTD_H 1 /* Added '1' for '#if' to work */
+
+/* Define if you have the dl library (-ldl).  */
+#define HAVE_LIBDL 1
+
+/* Define if you have the m library (-lm).  */
+#define HAVE_LIBM 1
+
+/* Define if you have the cuserid function.  */
+#define HAVE_CUSERID 0
+
+/* Define if you have the rint function.  */
+#undef HAVE_RINT
+
+#define HAVE_STRFTIME 1
+
+/* Default directory for loading extensions.  */
+#define PHP_EXTENSION_DIR "sys:/php/ext"
+
+#define SIZEOF_INT 4
+
+/* Define directory constants for php and pear */
+
+/* Venkat (20/12/01) */
+#define APACHE_MODULE_DIR "sys:/apache/modules"
+#define PHP_BINDIR "sys:/php"
+#define PHP_LIBDIR PHP_BINDIR
+#define PHP_DATADIR PHP_BINDIR
+#define PHP_SYSCONFDIR PHP_BINDIR
+#define PHP_LOCALSTATEDIR PHP_BINDIR
+#define PHP_CONFIG_FILE_PATH "sys:/php"
+#define PEAR_INSTALLDIR "sys:/php/pear"
+
diff --git a/netware/build.bat b/netware/build.bat
new file mode 100755 (executable)
index 0000000..5c8e310
--- /dev/null
@@ -0,0 +1,21 @@
+@echo off
+
+cd ..\%1
+
+if "%2" == "clean" make -f ..\netware\%1.mak clean
+if "%2" == "/?" goto USAGE
+
+if "%1" == "zend" call ..\netware\BisonFlexZend
+if "%1" == "ZendEngine2" call ..\netware\BisonFlexZend
+
+REM Build command
+make -f ..\netware\%1.mak
+goto EXIT
+
+:USAGE
+ @echo on
+ @echo Usage: build moduleName [clean]
+ @echo clean - delete all object files and binaries before building
+
+:EXIT
+cd ..\netware
\ No newline at end of file
diff --git a/netware/buildext.bat b/netware/buildext.bat
new file mode 100755 (executable)
index 0000000..6cea553
--- /dev/null
@@ -0,0 +1,18 @@
+@echo off
+
+cd ..\ext\%1
+
+if "%2" == "clean" make -f %1.mak clean
+if "%2" == "/?" goto USAGE
+
+REM Build command
+make -f %1.mak
+goto EXIT
+
+:USAGE
+ @echo on
+ @echo Usage: buildext extension_name [clean]
+ @echo clean - delete all object files and binaries before building
+
+:EXIT
+cd ..\..\netware
diff --git a/netware/buildsapi.bat b/netware/buildsapi.bat
new file mode 100755 (executable)
index 0000000..57498cb
--- /dev/null
@@ -0,0 +1,18 @@
+@echo off
+
+cd ..\sapi\%1
+
+if "%2" == "clean" make -f ..\..\netware\php4%1.mak clean
+if "%2" == "/?" goto USAGE
+
+REM Build command
+make -f ..\..\netware\php4%1.mak
+goto EXIT
+
+:USAGE
+ @echo on
+ @echo Usage: buildsapi SAPI_Module_Name [clean]
+ @echo clean - delete all object files and binaries before building
+
+:EXIT
+cd ..\..\netware
diff --git a/netware/common.mif b/netware/common.mif
new file mode 100644 (file)
index 0000000..d09026f
--- /dev/null
@@ -0,0 +1,73 @@
+#
+# common include file for PHP build
+# include this in every make file
+#
+
+# Set following directories based on your setting
+
+# Path to CodeWarrior installation
+CW_PATH = P:/APPS/SCRIPT/SW/CW71-4
+
+# NWSDK directories
+ifndef SDK_DIR
+SDK_DIR = R:/script/common/libc
+endif
+
+# MPK related directory
+ifndef MPK_DIR
+MPK_DIR = p:/apps/script/mpk
+endif
+
+#ifndef CLIB_DIR
+#CLIB_DIR = p:/apps/ndk0601/nwsdk
+#endif
+
+# Winsock stuff
+WINSOCK_DIR = P:/APPS/script/sw/Winsock2
+
+# LDAP stuff
+LDAP_DIR = P:/APPS/script/sw/cldapsdk
+
+# Apache directory
+ifndef APACHE_DIR
+APACHE_DIR = P:/APPS/script/sw/Apache1.3.xSource
+endif
+
+
+# CW includes, libraries and tools
+export MWCIncludes=$(CW_PATH)/include
+export MWLibraries=$(CW_PATH)/lib
+
+# Compiler and linker tools
+CC = mwccnlm
+LINK = mwldnlm
+
+# Build type defaults to 'release'
+ifndef BUILD
+BUILD = release
+endif
+#BUILD = debug
+
+OBJ_DIR = $(BUILD)
+FINAL_DIR = $(BUILD)
+MAP_FILE = $(FINAL_DIR)\$(MODULE_NAME).map
+
+ifndef STACK_SIZE
+STACK_SIZE=65536
+endif
+
+ifndef COPYRIGHT
+#COPYRIGHT = "Copyright (c) 1997-2002 The PHP Group. All Rights Reserved."
+COPYRIGHT = "Copyright (c) 1999\, 2000 The PHP Group. All rights reserved."
+endif
+
+# Link flags
+LD_FLAGS  = -stacksize $(STACK_SIZE) -type generic -zerobss
+LD_FLAGS += -o $(BINARY) -map $(MAP_FILE) -nlmversion $(VMAJ),$(VMIN),$(VREV)
+
+# Module details
+LD_FLAGS += -desc $(MODULE_DESC)
+LD_FLAGS += -copy $(COPYRIGHT)
+LD_FLAGS += -screenname Default
+LD_FLAGS += -threadname $(MODULE_NAME)__p
+
diff --git a/netware/mktemp.h b/netware/mktemp.h
new file mode 100644 (file)
index 0000000..b370438
--- /dev/null
@@ -0,0 +1 @@
+char* mktemp(char* templateStr);
diff --git a/netware/php4apache.mak b/netware/php4apache.mak
new file mode 100644 (file)
index 0000000..0fb9778
--- /dev/null
@@ -0,0 +1,161 @@
+# Temporarily here -- later may go into some batch file
+# which will set this as an environment variable
+PROJECT_ROOT = ../..
+
+# Module details
+MODULE_NAME = mod_php
+MODULE_DESC = "PHP 4.x.x for NetWare - mod_php"
+VMAJ = 0
+VMIN = 90
+VREV = 0
+
+#include the common settings
+include $(PROJECT_ROOT)/netware/common.mif
+
+# Extensions of all input and output files
+.SUFFIXES:
+.SUFFIXES: .nlm .lib .obj .cpp .c .msg .mlc .mdb .xdc .d
+
+# Source files
+C_SRC = mod_php4.c \
+        php_apache.c \
+        sapi_apache.c
+
+# Destination directories and files
+OBJ_DIR = $(BUILD)
+FINAL_DIR = $(BUILD)
+MAP_FILE = $(FINAL_DIR)\$(MODULE_NAME).map
+OBJECTS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC:.cpp=.obj) $(C_SRC:.c=.obj))
+DEPDS  = $(addprefix $(OBJ_DIR)/,$(CPP_SRC:.cpp=.d) $(C_SRC:.c=.d))
+
+# Binary file
+ifndef BINARY
+BINARY=$(FINAL_DIR)\$(MODULE_NAME).nlm
+endif
+
+
+# Compile flags
+C_FLAGS  = -c -maxerrors 25 -msgstyle gcc
+C_FLAGS += -wchar_t on -bool on
+C_FLAGS += -processor Pentium -align 1
+C_FLAGS += -w nounusedarg -msext on
+C_FLAGS += -nostdinc
+C_FLAGS += -DNETWARE -D__GNUC__
+C_FLAGS += -DZTS
+C_FLAGS += -DNLM_PLATFORM
+C_FLAGS += -DN_PLAT_NLM -DNLM=1 -D__NO_MATH_OPS
+C_FLAGS += -D__C9X_CMATH_INLINES_DEFINED -DAPACHE_OS_H -DNO_USE_SIGACTION -DMULTITHREAD
+C_FLAGS += -DCLIB_STAT_PATCH
+C_FLAGS += -DNEW_LIBC
+#C_FLAGS  += -DUSE_WINSOCK_DIRECTLY=1
+C_FLAGS += -I. -I- -I. -I../../netware -I$(SDK_DIR)/include    # ../../netware added for special SYS/STAT.H
+C_FLAGS += -I$(MWCIncludes)
+C_FLAGS += -I$(APACHE_DIR)/include -I$(APACHE_DIR)/os/netware
+C_FLAGS += -I- -I../../main -I../../Zend -I../../TSRM -I../../ext/standard
+C_FLAGS += -I../../ -I../../netware -I$(PROJECT_ROOT)/regex
+C_FLAGS += -I$(WINSOCK_DIR)/include/nlm -I$(WINSOCK_DIR)/include
+
+
+# Extra stuff based on debug / release builds
+ifeq '$(BUILD)' 'debug'
+       SYM_FILE = $(FINAL_DIR)\$(MODULE_NAME).sym
+       C_FLAGS  += -inline smart -sym on -sym codeview4 -opt off -opt intrinsics -sym internal -DDEBUGGING -DDKFBPON
+       C_FLAGS += -r -DZEND_DEBUG
+       C_FLAGS += -exc cw
+       LD_FLAGS += -sym on -sym codeview4 -sym internal -osym $(SYM_FILE) 
+        LD_FLAGS += -msgstyle std
+       export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtld.lib
+else
+       C_FLAGS  += -opt speed -inline on -inline smart -inline auto -sym off -DZEND_DEBUG=0
+       C_FLAGS += -opt intrinsics
+       C_FLAGS += -opt level=4
+       LD_FLAGS += -sym off
+       export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtl.lib
+endif
+
+# Dependencies
+MODULE = LibC \
+         phplib
+IMPORT = @$(SDK_DIR)/imports/libc.imp            \
+         @$(APACHE_DIR)/os/netware/apachecore.imp \
+         @$(PROJECT_ROOT)/netware/phplib.imp
+EXPORT = php4_module
+
+
+# Virtual paths
+vpath %.cpp .
+vpath %.c .
+vpath %.obj $(OBJ_DIR)
+
+
+all: prebuild project
+
+.PHONY: all
+
+prebuild:
+       @if not exist $(OBJ_DIR) md $(OBJ_DIR)
+
+project: $(BINARY) $(MESSAGE)
+       @echo Build complete.
+
+
+$(OBJ_DIR)/%.d: %.c
+       @echo Building Dependencies for $(<F)
+       @$(CC) -M $< $(C_FLAGS) -o $@
+
+$(OBJ_DIR)/%.obj: %.c
+       @echo Compiling $?...
+       @$(CC) $< $(C_FLAGS) -o $@
+
+
+$(BINARY): $(DEPDS) $(OBJECTS)
+       @echo Import $(IMPORT) > $(basename $@).def
+ifdef API
+       @echo Import $(API) >> $(basename $@).def
+endif
+       @echo Module $(MODULE) >> $(basename $@).def
+ifdef EXPORT
+       @echo Export $(EXPORT) >> $(basename $@).def
+endif
+       @echo AutoUnload >> $(basename $@).def
+ifeq '$(BUILD)' 'debug'
+       @echo Debug >> $(basename $@).def
+endif
+       @echo Flag_On 0x00000008 >> $(basename $@).def
+       @echo Start _lib_start >> $(basename $@).def
+       @echo Exit _lib_stop >> $(basename $@).def
+
+       @echo Linking $@...
+       @echo $(LD_FLAGS) -commandfile $(basename $@).def > $(basename $@).link
+ifdef LIBRARY
+       @echo $(LIBRARY) >> $(basename $@).link
+endif
+       @echo $(OBJECTS) $(APACHE_DIR)/os/netware/libpre.obj >> $(basename $@).link
+
+       @$(LINK) @$(basename $@).link
+
+
+.PHONY: clean
+clean: cleand cleanobj cleanbin
+
+.PHONY: cleand
+cleand:
+       @echo Deleting all dependency files...
+       -@del "$(OBJ_DIR)\*.d"
+
+.PHONY: cleanobj
+cleanobj:
+       @echo Deleting all object files...
+       -@del "$(OBJ_DIR)\*.obj"
+
+.PHONY: cleanbin
+cleanbin:
+       @echo Deleting binary files...
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).nlm"
+       @echo Deleting MAP, DEF files, etc....
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).map"
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).def"
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).link"
+ifeq '$(BUILD)' 'debug'
+       -@del $(FINAL_DIR)\$(MODULE_NAME).sym
+endif
diff --git a/netware/pwd.h b/netware/pwd.h
new file mode 100644 (file)
index 0000000..2a6ee73
--- /dev/null
@@ -0,0 +1,49 @@
+/*  pwd.h - Try to approximate UN*X's getuser...() functions under MS-DOS.
+   Copyright (C) 1990 by Thorsten Ohl, td12@ddagsi3.bitnet
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 1, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+/* This 'implementation' is conjectured from the use of this functions in
+   the RCS and BASH distributions.  Of course these functions don't do too
+   much useful things under MS-DOS, but using them avoids many "#ifdef
+   MSDOS" in ported UN*X code ...  */
+
+#ifndef PWD_H
+#define PWD_H
+
+/*
+    Not available in LibC / SDK header or CodeWarrior header files; so taking from Winsock
+    definitions, which should be OK
+*/
+typedef unsigned int DWORD;
+
+struct passwd {
+       char *pw_name;                          /* user name */
+       char *pw_passwd;                        /* encrypted password */
+       int pw_uid;                                     /* user uid */
+       int pw_gid;                                     /* user gid */
+       char *pw_comment;                       /* comment */
+       char *pw_gecos;                         /* Honeywell login info */
+       char *pw_dir;                           /* home directory */
+       char *pw_shell;                         /* default shell */
+};
+
+extern struct passwd *getpwuid(int);
+extern struct passwd *getpwnam(char *name);
+extern char *getlogin(void);
+
+#endif
diff --git a/netware/sys/stat.h b/netware/sys/stat.h
new file mode 100644 (file)
index 0000000..dc1ab91
--- /dev/null
@@ -0,0 +1,138 @@
+#ifndef __sys_stat_h__
+#define __sys_stat_h__
+/*============================================================================
+=  Novell Software Development Kit
+=
+=  Copyright (C) 1999-2002 Novell, Inc. All Rights Reserved.
+=
+=  This work is subject to U.S. and international copyright laws and treaties.
+=  Use and redistribution of this work is subject  to  the  license  agreement
+=  accompanying  the  software  development kit (SDK) that contains this work.
+=  However, no part of this work may be revised and/or  modified  without  the
+=  prior  written consent of Novell, Inc. Any use or exploitation of this work
+=  without authorization could subject the perpetrator to criminal  and  civil
+=  liability.
+=
+=  Source(s): ISO/IEC (POSIX) 9845:1996
+=
+=  sys/stat.h
+==============================================================================
+*/
+#include <time.h>
+#include <stddef.h>
+#include <sys/mode.h>
+#include <sys/time.h>
+
+#include <pshpack1.h>
+
+#ifdef CLIB_STAT_PATCH  /* Venkat (7/2/02) */
+/***************** stat structure taken from CLib and modified ***************/
+struct stat 
+{
+   long           st_dev;        /* volume number                         */    /* dev_t replaced by long : Venkat (19/3/02) */
+   MACHINE_WORD   st_ino;        /* directory entry number of the st_name */    /* ino_t replaced by MACHINE_WORD : Venkat (19/3/02) */
+   unsigned short st_mode;       /* emulated file mode                    */
+   unsigned short st_pad1;       /* reserved for alignment                */
+   unsigned long  st_nlink;      /* count of hard links (always 1)        */
+   unsigned long  st_uid;        /* object id of owner                    */
+   unsigned long  st_gid;        /* group-id (always 0)                   */
+   long           st_rdev;       /* device type (always 0)                */    /* dev_t replaced by long : Venkat (19/3/02) */
+   off_t          st_size;       /* total file size--files only           */
+   time_t         st_atime;      /* last access date--files only          */
+   time_t         st_mtime;      /* last modify date and time             */
+   time_t         st_ctime;      /* POSIX: last status change time...     */
+                                 /* ...NetWare: creation date/time        */
+   time_t         st_btime;      /* last archived date and time           */
+   unsigned long  st_attr;       /* file attributes                       */
+   unsigned long  st_archivedID; /* user/object ID of last archive        */
+   unsigned long  st_updatedID;  /* user/object ID of last update         */
+   unsigned short st_inheritedRightsMask;  /* inherited rights mask       */
+   unsigned short st_pad2;       /* reserved for alignment                */
+   unsigned int   st_originatingNameSpace; /* namespace of creation       */
+   size_t         st_blksize;    /* block size for allocation--files only */
+   size_t         st_blocks;     /* count of blocks allocated to file     */
+   unsigned int   st_flags;      /* user-defined flags                    */
+   unsigned long  st_spare[4];   /* for future use                        */
+   unsigned char  st_name[255+1];/* TARGET_NAMESPACE name                 */
+};
+/***************** stat structure taken from CLib and modified ***************/
+
+struct stat_libc
+{
+   uint32_t   st_userspec; /* untouched by stat()                   */
+   uint32_t   st_flags;    /* flags for this entry                  */
+   mode_t     st_mode;     /* emulated file mode                    */
+   uint32_t   st_spare1;
+   uint64_t   st_gen;      /* generation number of inode            */
+   ino_t      st_ino;      /* directory entry number                */
+   dev_t      st_dev;      /* volume number                         */
+   dev_t      st_rdev;     /* device type (always 0)                */
+   off64_t    st_size;     /* total file size                       */
+   uint64_t   st_spare2;
+   blkcnt_t   st_blocks;   /* count of blocks allocated to file     */
+   blksize_t  st_blksize;  /* block size for allocation--files only */
+   nlink_t    st_nlink;    /* count of hard links (always 1)        */
+   uint32_t   st_spare3[3];
+   uid_t      st_uid;      /* owner (object) identity               */
+   gid_t      st_gid;      /* group-id (always 0)                   */
+   uid_t      st_bid;      /* identity of last archiver             */
+   uid_t      st_mid;      /* identity of last updator              */
+   timespec_t st_atime;    /* last access date--files only          */
+   timespec_t st_mtime;    /* last modify date and time             */
+   timespec_t st_ctime;    /* last file attributes modification     */
+   timespec_t st_btime;    /* last archived date and time           */
+   uint64_t   st_spare4[44];
+};                         /* sizeof(struct dirent) == 0x200 (512.) */
+
+#else
+struct stat
+{
+   uint32_t   st_userspec; /* untouched by stat()                   */
+   uint32_t   st_flags;    /* flags for this entry                  */
+   mode_t     st_mode;     /* emulated file mode                    */
+   uint32_t   st_spare1;
+   uint64_t   st_gen;      /* generation number of inode            */
+   ino_t      st_ino;      /* directory entry number                */
+   dev_t      st_dev;      /* volume number                         */
+   dev_t      st_rdev;     /* device type (always 0)                */
+   off64_t    st_size;     /* total file size                       */
+   uint64_t   st_spare2;
+   blkcnt_t   st_blocks;   /* count of blocks allocated to file     */
+   blksize_t  st_blksize;  /* block size for allocation--files only */
+   nlink_t    st_nlink;    /* count of hard links (always 1)        */
+   uint32_t   st_spare3[3];
+   uid_t      st_uid;      /* owner (object) identity               */
+   gid_t      st_gid;      /* group-id (always 0)                   */
+   uid_t      st_bid;      /* identity of last archiver             */
+   uid_t      st_mid;      /* identity of last updator              */
+   timespec_t st_atime;    /* last access date--files only          */
+   timespec_t st_mtime;    /* last modify date and time             */
+   timespec_t st_ctime;    /* last file attributes modification     */
+   timespec_t st_btime;    /* last archived date and time           */
+   uint64_t   st_spare4[44];
+};                         /* sizeof(struct dirent) == 0x200 (512.) */
+#endif
+
+#include <poppack.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int    chmod ( const char *path,     mode_t mode        );
+int    fchmod( int fildes,           mode_t mode        );
+int    fstat ( int fildes,           struct stat *buf );
+int    mkdir ( const char *pathname, mode_t mode        );
+int    mkfifo( const char *pathname, mode_t mode        );
+int    stat  ( const char *path,     struct stat *buf );
+mode_t umask (                       mode_t cmask       );
+
+#ifdef __cplusplus
+}
+#endif
+
+#define stat64  stat       /* same structure and function do both   */
+#define fstat64 fstat      /* same function does both               */
+
+#endif
diff --git a/netware/tsrm.mak b/netware/tsrm.mak
new file mode 100644 (file)
index 0000000..9460393
--- /dev/null
@@ -0,0 +1,108 @@
+# Temporarily here -- later may go into some batch file
+# which will set this as an environment variable
+PROJECT_ROOT = ..
+
+# Module details
+MODULE_NAME = TSRM
+
+#MODULE_ROOT = $(PROJECT_ROOT)\\$(MODULE_NAME)
+
+#include the common settings
+include $(PROJECT_ROOT)/netware/common.mif
+
+# Extensions of all input and output files
+.SUFFIXES:
+.SUFFIXES: .nlm .lib .obj .cpp .c .msg .mlc .mdb .xdc .d
+
+# Source files
+CPP_SRC = 
+C_SRC = TSRM.c \
+        tsrm_strtok_r.c \
+        tsrm_virtual_cwd.c \
+        tsrm_nw.c
+
+# Destination directories and files
+OBJ_DIR = $(BUILD)
+FINAL_DIR = $(BUILD)
+OBJECTS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC:.cpp=.obj) $(C_SRC:.c=.obj))
+DEPDS  = $(addprefix $(OBJ_DIR)/,$(CPP_SRC:.cpp=.d) $(C_SRC:.c=.d))
+
+# Binary file
+ifndef BINARY
+       BINARY=$(FINAL_DIR)\$(MODULE_NAME).lib
+endif
+
+# Compile flags
+C_FLAGS  = -c -maxerrors 25 -msgstyle gcc
+C_FLAGS += -wchar_t on -bool on
+C_FLAGS += -processor Pentium -align 1
+C_FLAGS += -nostdinc
+C_FLAGS  += -DZTS -DNETWARE -DHAVE_DIRENT_H
+#C_FLAGS  += -DUSE_PIPE_OPEN
+C_FLAGS  += -DUSE_MKFIFO
+C_FLAGS  += -DCLIB_STAT_PATCH -DUSE_MPK
+C_FLAGS  += -I. -I- -I../netware -I$(SDK_DIR)/include  # ../netware added for special SYS/STAT.H
+C_FLAGS  += -I$(MPK_DIR)/include1
+C_FLAGS  += -I$(MWCIncludes)
+
+# Link flags
+LD_FLAGS  = -type library
+LD_FLAGS += -o $(BINARY)
+
+# Extra stuff based on debug / release builds
+ifeq '$(BUILD)' 'debug'
+       C_FLAGS  += -inline smart -sym on -sym codeview4 -sym internal -opt off -opt intrinsics -DTSRM_DEBUG=1
+       LD_FLAGS += -sym codeview4 -sym internal
+       export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtld.lib
+else
+       C_FLAGS  += -opt speed -inline smart -inline auto -sym off -DTSRM_DEBUG=0
+       LD_FLAGS += -sym off
+       export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtl.lib
+endif
+
+# Virtual paths
+vpath %.cpp .
+vpath %.c .
+vpath %.obj $(OBJ_DIR)
+
+
+all: prebuild project
+
+.PHONY: all
+
+prebuild:
+       @if not exist $(OBJ_DIR) md $(OBJ_DIR)
+
+project: $(BINARY) $(MESSAGE)
+       @echo Build complete.
+
+$(OBJ_DIR)/%.d: %.c
+       @echo Building Dependencies for $(<F)
+       @$(CC) -M $< $(C_FLAGS) -o $@
+       
+$(OBJ_DIR)/%.obj: %.c
+       @echo Compiling $?...
+       @$(CC) $< $(C_FLAGS) -o $@
+
+$(BINARY): $(DEPDS) $(OBJECTS)
+       @echo Linking $@...
+       @$(LINK) $(LD_FLAGS) $(OBJECTS)
+
+
+.PHONY: clean
+clean: cleand cleanobj cleanbin
+
+.PHONY: cleand
+cleand:
+       @echo Deleting all dependency files...
+       -@del "$(OBJ_DIR)\*.d"
+
+.PHONY: cleanobj
+cleanobj:
+       @echo Deleting all object files...
+       -@del "$(OBJ_DIR)\*.obj"
+
+.PHONY: cleanbin
+cleanbin:
+       @echo Deleting binary files...
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).lib"
diff --git a/netware/zend.mak b/netware/zend.mak
new file mode 100644 (file)
index 0000000..5181cc0
--- /dev/null
@@ -0,0 +1,163 @@
+# Temporarily here -- later may go into some batch file
+# which will set this as an environment variable
+PROJECT_ROOT = ..
+
+# Module details
+MODULE_NAME = ZEND
+
+#MODULE_ROOT = $(PROJECT_ROOT)\\$(MODULE_NAME)
+
+#include the common settings
+include $(PROJECT_ROOT)/netware/common.mif
+
+# Extensions of all input and output files
+.SUFFIXES:
+.SUFFIXES: .nlm .lib .obj .cpp .c .msg .mlc .mdb .xdc .d
+
+C_SRC = zend.c \
+        zend_alloc.c \
+        zend_API.c \
+        zend_builtin_functions.c \
+        zend_compile.c \
+        zend_constants.c \
+        zend_dynamic_array.c \
+        zend_execute.c \
+        zend_execute_API.c \
+        zend_extensions.c \
+        zend_hash.c \
+        zend_highlight.c \
+        zend_indent.c \
+        zend_ini.c \
+        zend_list.c \
+        zend_llist.c \
+        zend_opcode.c \
+        zend_operators.c \
+        zend_ptr_stack.c \
+        zend_qsort.c \
+        zend_sprintf.c \
+        zend_stack.c \
+        zend_static_allocator.c \
+        zend_variables.c \
+        zend_ini_parser.c \
+        zend_ini_scanner.c \
+        zend_language_parser.c \
+        zend_language_scanner.c
+
+
+# Destination directories and files
+OBJ_DIR = $(BUILD)
+FINAL_DIR = $(BUILD)
+OBJECTS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC:.cpp=.obj) $(C_SRC:.c=.obj))
+DEPDS  = $(addprefix $(OBJ_DIR)/,$(CPP_SRC:.cpp=.d) $(C_SRC:.c=.d))
+
+# Binary file
+ifndef BINARY
+       BINARY=$(FINAL_DIR)\$(MODULE_NAME).lib
+endif
+
+
+# Compile flags
+C_FLAGS  = -c -maxerrors 25 -msgstyle std
+C_FLAGS += -wchar_t on -bool on
+C_FLAGS += -processor Pentium -align 1
+C_FLAGS += -nostdinc
+C_FLAGS += -D__C9X_CMATH_INLINES_DEFINED
+C_FLAGS += -DNETWARE -D__GNUC__
+C_FLAGS += -DZTS
+C_FLAGS += -DCLIB_STAT_PATCH
+C_FLAGS += -DTHREAD_SWITCH
+C_FLAGS += -I. -I- -I../netware -I$(SDK_DIR)/include   # ../netware added for special SYS/STAT.H
+C_FLAGS += -I$(MWCIncludes)
+
+# Link flags
+LD_FLAGS  = -type library
+LD_FLAGS += -o $(BINARY)
+
+
+# Extra stuff based on debug / release builds
+ifeq '$(BUILD)' 'debug'
+       C_FLAGS  += -DZEND_DEBUG
+       C_FLAGS  += -inline smart -sym on -sym codeview4 -sym internal -opt off -opt intrinsics
+       LD_FLAGS += -sym codeview4 -sym internal
+       export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtld.lib
+else
+       C_FLAGS  += -opt speed -inline on -inline auto -sym off
+       LD_FLAGS += -sym off
+       export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtl.lib
+endif
+
+
+# Virtual paths
+vpath %.cpp .
+vpath %.c .
+vpath %.obj $(OBJ_DIR)
+
+
+all: prebuild project
+
+.PHONY: all
+
+prebuild:
+       @if not exist $(OBJ_DIR) md $(OBJ_DIR)
+
+project: $(BINARY) $(MESSAGE)
+       @echo Build complete.
+
+
+##zend_ini_parser.c zend_ini_parser.h : zend_ini_parser.y
+##     @bison --output=$@ -v -d -p ini_ zend_ini_parser.y
+
+##zend_ini_scanner.c : zend_ini_scanner.l
+##     @flex -i -Pini_ -o$@ zend_ini_scanner.l
+
+##zend_language_parser.c zend_language_parser.h : zend_language_parser.y
+##     @bison --output=$@ -v -d -p zend zend_language_parser.y
+
+##zend_language_scanner.c : zend_language_scanner.l
+##     @flex -i -Pzend -o$@ zend_language_scanner.l
+
+$(OBJ_DIR)/%.d: %.c
+       @echo Building Dependencies for $(<F)
+       @$(CC) -M $< $(C_FLAGS) -o $@
+       
+$(OBJ_DIR)/%.obj: %.c
+       @echo Compiling $?...
+       @$(CC) $< $(C_FLAGS) -o $@
+
+
+$(BINARY): $(DEPDS) $(OBJECTS)
+       @echo Linking $@...
+       @$(LINK) $(LD_FLAGS) $(OBJECTS)
+
+
+.PHONY: clean
+clean: cleansrc cleand cleanobj cleanbin
+
+.PHONY: cleansrc
+cleansrc:
+       @echo Deleting all generated source files...
+       -@del "zend_ini_parser.c"
+       -@del "zend_ini_parser.h"
+       -@del "zend_ini_scanner.c"
+       -@del "zend_language_parser.c"
+       -@del "zend_language_parser.h"
+       -@del "zend_language_scanner.c"
+       -@del "zend_ini_parser.output"
+       -@del "zend_language_parser.output"
+
+
+.PHONY: cleand
+cleand:
+       @echo Deleting all dependency files...
+       -@del "$(OBJ_DIR)\*.d"
+
+.PHONY: cleanobj
+cleanobj:
+       @echo Deleting all object files...
+       -@del "$(OBJ_DIR)\*.obj"
+
+.PHONY: cleanbin
+cleanbin:
+       @echo Deleting binary files...
+       -@del "$(FINAL_DIR)\$(MODULE_NAME).lib"
+