--- /dev/null
+#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
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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;
+}
+
+
--- /dev/null
+# 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
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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;
+}
+
+
--- /dev/null
+--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
--- /dev/null
+/* 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"
+
--- /dev/null
+@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
--- /dev/null
+@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
--- /dev/null
+@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
--- /dev/null
+#
+# 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
+
--- /dev/null
+char* mktemp(char* templateStr);
--- /dev/null
+# 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
--- /dev/null
+/* 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
--- /dev/null
+#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
--- /dev/null
+# 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"
--- /dev/null
+# 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"
+