summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>1999-04-07 21:05:13 +0000
committerZeev Suraski <zeev@php.net>1999-04-07 21:05:13 +0000
commitaceaabceffd537a0ed83fa25e189b08eae585f4a (patch)
treebcef55f16a2ae57c1c883b34347f9e6906ca6dfe /win32
parentd94f3e22ae6fe17d82b189dc362e975a906f919a (diff)
downloadphp-git-aceaabceffd537a0ed83fa25e189b08eae585f4a.tar.gz
PHP 4.0
Diffstat (limited to 'win32')
-rw-r--r--win32/flock.c83
-rw-r--r--win32/flock.h11
-rw-r--r--win32/grp.h31
-rw-r--r--win32/param.h16
-rw-r--r--win32/pwd.c79
-rw-r--r--win32/pwd.h57
-rw-r--r--win32/readdir.c111
-rw-r--r--win32/readdir.h37
-rw-r--r--win32/sendmail.c511
-rw-r--r--win32/sendmail.h46
-rw-r--r--win32/signal.h4
-rw-r--r--win32/syslog.h73
-rw-r--r--win32/time.c156
-rw-r--r--win32/time.h40
-rw-r--r--win32/unistd.h1
-rw-r--r--win32/wfile.c17
-rw-r--r--win32/wfile.h16
-rw-r--r--win32/winutil.c29
-rw-r--r--win32/winutil.h1
-rw-r--r--win32/wsyslog.c128
20 files changed, 1447 insertions, 0 deletions
diff --git a/win32/flock.c b/win32/flock.c
new file mode 100644
index 0000000000..cc9d409784
--- /dev/null
+++ b/win32/flock.c
@@ -0,0 +1,83 @@
+/*
+ * Program: Unix compatibility routines
+ *
+ * Author: Mark Crispin
+ * Networks and Distributed Computing
+ * Computing & Communications
+ * University of Washington
+ * Administration Building, AG-44
+ * Seattle, WA 98195
+ * Internet: MRC@CAC.Washington.EDU
+ *
+ * Date: 14 September 1996
+ * Last Edited: 14 August 1997
+ *
+ * Copyright 1997 by the University of Washington
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appears in all copies and that both the
+ * above copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the University of Washington not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. This software is made available
+ * "as is", and
+ * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+ * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
+ * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+
+/* DEDICATION
+
+ * This file is dedicated to my dog, Unix, also known as Yun-chan and
+ * Unix J. Terwilliker Jehosophat Aloysius Monstrosity Animal Beast. Unix
+ * passed away at the age of 11 1/2 on September 14, 1996, 12:18 PM PDT, after
+ * a two-month bout with cirrhosis of the liver.
+ *
+ * He was a dear friend, and I miss him terribly.
+ *
+ * Lift a leg, Yunie. Luv ya forever!!!!
+ */
+
+#include <windows.h>
+#include <io.h>
+#include <errno.h>
+#include "flock.h"
+
+int flock(int fd, int op)
+{
+ HANDLE hdl = (HANDLE) _get_osfhandle(fd);
+ DWORD low = 1, high = 0;
+ OVERLAPPED offset =
+ {0, 0, 0, 0, NULL};
+ if (hdl < 0)
+ return -1; /* error in file descriptor */
+ /* bug for bug compatible with Unix */
+ UnlockFileEx(hdl, 0, low, high, &offset);
+ switch (op & ~LOCK_NB) { /* translate to LockFileEx() op */
+ case LOCK_EX: /* exclusive */
+ if (LockFileEx(hdl, LOCKFILE_EXCLUSIVE_LOCK +
+ ((op & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0),
+ 0, low, high, &offset))
+ return 0;
+ break;
+ case LOCK_SH: /* shared */
+ if (LockFileEx(hdl, ((op & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0),
+ 0, low, high, &offset))
+ return 0;
+ break;
+ case LOCK_UN: /* unlock */
+ return 0; /* always succeeds */
+ default: /* default */
+ break;
+ }
+ errno = EINVAL; /* bad call */
+ return -1;
+}
diff --git a/win32/flock.h b/win32/flock.h
new file mode 100644
index 0000000000..fe07adf954
--- /dev/null
+++ b/win32/flock.h
@@ -0,0 +1,11 @@
+#define fsync _commit
+#define ftruncate chsize
+
+/* For flock() emulation */
+
+#define LOCK_SH 1
+#define LOCK_EX 2
+#define LOCK_NB 4
+#define LOCK_UN 8
+
+extern int flock(int fd, int op);
diff --git a/win32/grp.h b/win32/grp.h
new file mode 100644
index 0000000000..e7a99327e2
--- /dev/null
+++ b/win32/grp.h
@@ -0,0 +1,31 @@
+/* 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.
+
+ $Header$
+ */
+
+/* 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 ... */
+
+struct group {
+ char *gr_name; /* group name */
+ char *gr_passwd; /* group password */
+ int gr_gid; /* group id */
+ char **gr_mem; /* group members */
+};
diff --git a/win32/param.h b/win32/param.h
new file mode 100644
index 0000000000..3d0da1e8d3
--- /dev/null
+++ b/win32/param.h
@@ -0,0 +1,16 @@
+
+/*****************************************************************************
+ * *
+ * sys/param.c *
+ * *
+ * Freely redistributable and modifiable. Use at your own risk. *
+ * *
+ * Copyright 1994 The Downhill Project *
+ * *
+ *****************************************************************************/
+#ifndef MAXPATHLEN
+#define MAXPATHLEN _MAX_PATH
+#endif
+#define MAXHOSTNAMELEN 64
+#define howmany(x,y) (((x)+((y)-1))/(y))
+#define roundup(x,y) ((((x)+((y)-1))/(y))*(y))
diff --git a/win32/pwd.c b/win32/pwd.c
new file mode 100644
index 0000000000..e6d709d750
--- /dev/null
+++ b/win32/pwd.c
@@ -0,0 +1,79 @@
+/* pwd.c - 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.
+
+ $Header$
+ */
+
+/* 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 ... */
+
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include "php.h" /*php specific */
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <lmaccess.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lmapibuf.h>
+#include "pwd.h"
+#include "grp.h"
+
+#ifndef THREAD_SAFE
+static struct passwd pw; /* should we return a malloc()'d structure */
+#endif
+static char *home_dir = "."; /* we feel (no|every)where at home */
+static char *login_shell = "not command.com!";
+
+struct passwd *getpwnam(char *name)
+{
+ return (struct passwd *) 0;
+}
+
+
+char *getlogin()
+{
+ static char name[256];
+ DWORD dw = 256;
+ GetUserName(name, &dw);
+ return name;
+}
+
+struct passwd *
+ getpwuid(int uid)
+{
+ TLS_VARS;
+
+ GLOBAL(pw).pw_name = getlogin();
+ GLOBAL(pw).pw_dir = home_dir;
+ GLOBAL(pw).pw_shell = login_shell;
+ GLOBAL(pw).pw_uid = 0;
+
+ return &GLOBAL(pw);
+}
+
+/*
+ * Local Variables:
+ * mode:C
+ * ChangeLog:ChangeLog
+ * compile-command:make
+ * End:
+ */
diff --git a/win32/pwd.h b/win32/pwd.h
new file mode 100644
index 0000000000..d0ae7ac35b
--- /dev/null
+++ b/win32/pwd.h
@@ -0,0 +1,57 @@
+/* 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.
+
+ $Header$
+ */
+
+/* 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 ... */
+/*
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+ */
+#ifndef _PWD_H_
+#define _PWD_H_
+#if 0
+/* This is taken care of in Windows-NT/config.h. */
+typedef int uid_t;
+#endif
+
+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
+/*
+ * Local Variables:
+ * mode:C
+ * ChangeLog:ChangeLog
+ * compile-command:make
+ * End:
+ */
diff --git a/win32/readdir.c b/win32/readdir.c
new file mode 100644
index 0000000000..2ebec905e3
--- /dev/null
+++ b/win32/readdir.c
@@ -0,0 +1,111 @@
+#include <malloc.h>
+#include <string.h>
+#include <errno.h>
+
+#define NEEDRDH 1
+#include "readdir.h"
+
+/**********************************************************************
+ * Implement dirent-style opendir/readdir/closedir on Window 95/NT
+ *
+ * Functions defined are opendir(), readdir() and closedir() with the
+ * same prototypes as the normal dirent.h implementation.
+ *
+ * Does not implement telldir(), seekdir(), rewinddir() or scandir().
+ * The dirent struct is compatible with Unix, except that d_ino is
+ * always 1 and d_off is made up as we go along.
+ *
+ * The DIR typedef is not compatible with Unix.
+ **********************************************************************/
+
+DIR *opendir(const char *dir)
+{
+ DIR *dp;
+ char *filespec;
+ long handle;
+ int index;
+
+ filespec = malloc(strlen(dir) + 2 + 1);
+ strcpy(filespec, dir);
+ index = strlen(filespec) - 1;
+ if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
+ filespec[index] = '\0';
+ strcat(filespec, "/*");
+
+ dp = (DIR *) malloc(sizeof(DIR));
+ dp->offset = 0;
+ dp->finished = 0;
+ dp->dir = strdup(dir);
+
+ if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) {
+ if (errno == ENOENT)
+ dp->finished = 1;
+ else
+ return NULL;
+ }
+ dp->handle = handle;
+ free(filespec);
+
+ return dp;
+}
+
+struct dirent *readdir(DIR * dp)
+{
+ if (!dp || dp->finished)
+ return NULL;
+
+ if (dp->offset != 0) {
+ if (_findnext(dp->handle, &(dp->fileinfo)) < 0) {
+ dp->finished = 1;
+ return NULL;
+ }
+ }
+ dp->offset++;
+
+ strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
+ dp->dent.d_ino = 1;
+ dp->dent.d_reclen = strlen(dp->dent.d_name);
+ dp->dent.d_off = dp->offset;
+
+ return &(dp->dent);
+}
+
+int closedir(DIR * dp)
+{
+ if (!dp)
+ return 0;
+ _findclose(dp->handle);
+ if (dp->dir)
+ free(dp->dir);
+ if (dp)
+ free(dp);
+
+ return 0;
+}
+
+void rewinddir(DIR *dir_Info)
+{
+ /* Re-set to the beginning */
+ char *filespec;
+ long handle;
+ int index;
+
+ dir_Info->handle = 0;
+ dir_Info->offset = 0;
+ dir_Info->finished = 0;
+
+ filespec = malloc(strlen(dir_Info->dir) + 2 + 1);
+ strcpy(filespec, dir_Info->dir);
+ index = strlen(filespec) - 1;
+ if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\'))
+ filespec[index] = '\0';
+ strcat(filespec, "/*");
+
+ if ((handle = _findfirst(filespec, &(dir_Info->fileinfo))) < 0) {
+ if (errno == ENOENT) {
+ dir_Info->finished = 1;
+ }
+ }
+ dir_Info->handle = handle;
+ free(filespec);
+}
diff --git a/win32/readdir.h b/win32/readdir.h
new file mode 100644
index 0000000000..febaff2798
--- /dev/null
+++ b/win32/readdir.h
@@ -0,0 +1,37 @@
+/*
+ * Structures and types used to implement opendir/readdir/closedir
+ * on Windows 95/NT.
+ */
+
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+
+/* struct dirent - same as Unix */
+#if NEEDRDH
+
+struct dirent {
+ long d_ino; /* inode (always 1 in WIN32) */
+ off_t d_off; /* offset to this dirent */
+ unsigned short d_reclen; /* length of d_name */
+ char d_name[_MAX_FNAME + 1]; /* filename (null terminated) */
+};
+
+/* typedef DIR - not the same as Unix */
+typedef struct {
+ long handle; /* _findfirst/_findnext handle */
+ short offset; /* offset into directory */
+ short finished; /* 1 if there are not more files */
+ struct _finddata_t fileinfo; /* from _findfirst/_findnext */
+ char *dir; /* the dir we are reading */
+ struct dirent dent; /* the dirent to return */
+} DIR;
+
+/* Function prototypes */
+extern DIR *opendir(const char *);
+extern struct dirent *readdir(DIR *);
+extern int closedir(DIR *);
+#endif
+extern void rewinddir(DIR *);
diff --git a/win32/sendmail.c b/win32/sendmail.c
new file mode 100644
index 0000000000..7adf4d7bf3
--- /dev/null
+++ b/win32/sendmail.c
@@ -0,0 +1,511 @@
+
+/*
+ * PHP Sendmail for Windows.
+ *
+ * This file is rewriten specificly for PHPFI. Some functionality
+ * has been removed (MIME and file attachments). This code was
+ * modified from code based on code writen by Jarle Aase.
+ *
+ * This class is based on the original code by Jarle Aase, see bellow:
+ * wSendmail.cpp It has been striped of some functionality to match
+ * the requirements of phpfi.
+ *
+ * Very simple SMTP Send-mail program for sending command-line level
+ * emails and CGI-BIN form response for the Windows platform.
+ *
+ * The complete wSendmail package with source code can be downloaded
+ * from http://virtual.icr.com.au:80/jgaa/cgi-bin.htm
+ *
+ */
+
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include "php.h" /*php specific */
+#include <stdio.h>
+#include <stdlib.h>
+#include <winsock.h>
+#include "time.h"
+#include <string.h>
+#include <malloc.h>
+#include <memory.h>
+#include <winbase.h>
+#include "sendmail.h"
+
+
+/*
+ extern int _daylight;
+ extern long _timezone;
+ */
+/*enum
+ {
+ DO_CONNECT = WM_USER +1
+ };
+ */
+
+static char *days[] =
+{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+static char *months[] =
+{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+#ifndef THREAD_SAFE
+char Buffer[MAIL_BUFFER_SIZE];
+
+// socket related data
+SOCKET sc;
+WSADATA Data;
+struct hostent *adr;
+SOCKADDR_IN sock_in;
+int WinsockStarted;
+// values set by the constructor
+char *AppName;
+char MailHost[HOST_NAME_LEN];
+char LocalHost[HOST_NAME_LEN];
+#endif
+char seps[] = " ,\t\n";
+char *php_mailer = "PHP 3.0 WIN32";
+
+char *get_header(char *h, char *headers);
+
+// Error messages
+static char *ErrorMessages[] =
+{
+ {"Success"},
+ {"Bad arguments from form"},
+ {"Unable to open temporary mailfile for read"},
+ {"Failed to Start Sockets"},
+ {"Failed to Resolve Host"},
+ {"Failed to obtain socket handle"},
+ {"Failed to Connect"},
+ {"Failed to Send"},
+ {"Failed to Receive"},
+ {"Server Error"},
+ {"Failed to resolve the host IP name"},
+ {"Out of memory"},
+ {"Unknown error"},
+ {"Bad Message Contents"},
+ {"Bad Message Subject"},
+ {"Bad Message destination"},
+ {"Bad Message Return Path"},
+ {"Bad Mail Host"},
+ {"Bad Message File"},
+ {"PHP Internal error: php3.ini sendmail from variable not set!"}
+};
+
+
+
+//********************************************************************
+// Name: TSendMail
+// Input: 1) host: Name of the mail host where the SMTP server resides
+// max accepted length of name = 256
+// 2) appname: Name of the application to use in the X-mailer
+// field of the message. if NULL is given the application
+// name is used as given by the GetCommandLine() function
+// max accespted length of name = 100
+// Output: 1) error: Returns the error code if something went wrong or
+// SUCCESS otherwise.
+//
+// See SendText() for additional args!
+//********************************************************************
+int TSendMail(char *host, int *error,
+ char *headers, char *Subject, char *mailTo, char *data)
+{
+ int ret;
+ char *RPath = NULL;
+ TLS_VARS;
+
+ GLOBAL(WinsockStarted) = FALSE;
+
+ if (host == NULL) {
+ *error = BAD_MAIL_HOST;
+ return BAD_MAIL_HOST;
+ } else if (strlen(host) >= HOST_NAME_LEN) {
+ *error = BAD_MAIL_HOST;
+ return BAD_MAIL_HOST;
+ } else {
+ strcpy(GLOBAL(MailHost), host);
+ }
+
+ if (php3_ini.sendmail_from){
+ RPath = estrdup(php3_ini.sendmail_from);
+ } else {
+ return 19;
+ }
+
+ // attempt to connect with mail host
+ *error = MailConnect();
+ if (*error != 0) {
+ if(RPath)efree(RPath);
+ return *error;
+ } else {
+ ret = SendText(RPath, Subject, mailTo, data, headers);
+ TSMClose();
+ if (ret != SUCCESS) {
+ *error = ret;
+ }
+ if(RPath)efree(RPath);
+ return ret;
+ }
+}
+
+//********************************************************************
+// Name: TSendMail::~TSendMail
+// Input:
+// Output:
+// Description: DESTRUCTOR
+// Author/Date: jcar 20/9/96
+// History:
+//********************************************************************
+void TSMClose()
+{
+ TLS_VARS;
+
+ Post("QUIT\n");
+ Ack();
+ // to guarantee that the cleanup is not made twice and
+ // compomise the rest of the application if sockets are used
+ // elesewhere
+}
+
+
+//********************************************************************
+// Name: char *GetSMErrorText
+// Input: Error index returned by the menber functions
+// Output: pointer to a string containing the error description
+// Description:
+// Author/Date: jcar 20/9/96
+// History:
+//********************************************************************
+char *GetSMErrorText(int index)
+{
+
+ if ((index > MAX_ERROR_INDEX) || (index < MIN_ERROR_INDEX))
+ return (ErrorMessages[UNKNOWN_ERROR]);
+ else
+ return (ErrorMessages[index]);
+}
+
+
+//********************************************************************
+// Name: TSendText
+// Input: 1) RPath: return path of the message
+// Is used to fill the "Return-Path" and the
+// "X-Sender" fields of the message.
+// 2) Subject: Subject field of the message. If NULL is given
+// the subject is set to "No Subject"
+// 3) mailTo: Destination address
+// 4) data: Null terminated string containing the data to be send.
+// Output: Error code or SUCCESS
+// Description:
+// Author/Date: jcar 20/9/96
+// History:
+//********************************************************************
+int SendText(char *RPath, char *Subject, char *mailTo, char *data, char *headers)
+{
+
+ int res, i;
+ char *p;
+ TLS_VARS;
+
+ // check for NULL parameters
+ if (data == NULL)
+ return (BAD_MSG_CONTENTS);
+ if (mailTo == NULL)
+ return (BAD_MSG_DESTINATION);
+ if (RPath == NULL)
+ return (BAD_MSG_RPATH);
+
+ // simple checks for the mailto address
+ // have ampersand ?
+ if (strchr(mailTo, '@') == NULL)
+ return (BAD_MSG_DESTINATION);
+
+ sprintf(GLOBAL(Buffer), "HELO %s\n", GLOBAL(LocalHost));
+
+ // in the beggining of the dialog
+ // attempt reconnect if the first Post fail
+ if ((res = Post(GLOBAL(Buffer))) != SUCCESS) {
+ MailConnect();
+ if ((res = Post(GLOBAL(Buffer))) != SUCCESS)
+ return (res);
+ }
+ if ((res = Ack()) != SUCCESS)
+ return (res);
+
+ sprintf(GLOBAL(Buffer), "MAIL FROM:<%s>\n", RPath);
+ if ((res = Post(GLOBAL(Buffer))) != SUCCESS)
+ return (res);
+ if ((res = Ack()) != SUCCESS)
+ return (res);
+
+
+ sprintf(GLOBAL(Buffer), "RCPT TO:<%s>\n", mailTo);
+ if ((res = Post(GLOBAL(Buffer))) != SUCCESS)
+ return (res);
+ if ((res = Ack()) != SUCCESS)
+ return (res);
+
+ if ((res = Post("DATA\n")) != SUCCESS)
+ return (res);
+ if ((res = Ack()) != SUCCESS)
+ return (res);
+
+
+ // send message header
+ if (Subject == NULL)
+ res = PostHeader(RPath, "No Subject", mailTo, headers);
+ else
+ res = PostHeader(RPath, Subject, mailTo, headers);
+ if (res != SUCCESS)
+ return (res);
+
+
+ // send message contents in 1024 chunks
+ if (strlen(data) <= 1024) {
+ if ((res = Post(data)) != SUCCESS)
+ return (res);
+ } else {
+ p = data;
+ while (1) {
+ if (*p == '\0')
+ break;
+ if (strlen(p) >= 1024)
+ i = 1024;
+ else
+ i = strlen(p);
+
+ // put next chunk in buffer
+ strncpy(GLOBAL(Buffer), p, i);
+ GLOBAL(Buffer)[i] = '\0';
+ p += i;
+
+ // send chunk
+ if ((res = Post(GLOBAL(Buffer))) != SUCCESS)
+ return (res);
+ }
+ }
+
+ //send termination dot
+ if ((res = Post("\r\n.\r\n")) != SUCCESS)
+ return (res);
+ if ((res = Ack()) != SUCCESS)
+ return (res);
+
+ return (SUCCESS);
+}
+
+
+
+//********************************************************************
+// Name: PostHeader
+// Input: 1) return path
+// 2) Subject
+// 3) destination address
+// 4) DoMime flag
+// Output: Error code or Success
+// Description:
+// Author/Date: jcar 20/9/96
+// History:
+//********************************************************************
+int PostHeader(char *RPath, char *Subject, char *mailTo, char *xheaders)
+{
+
+ // Print message header according to RFC 822
+ // Return-path, Received, Date, From, Subject, Sender, To, cc
+
+ time_t tNow = time(NULL);
+ struct tm *tm = localtime(&tNow);
+ int zoneh = abs(_timezone);
+ int zonem, res;
+ char *p;
+ TLS_VARS;
+
+ p = GLOBAL(Buffer);
+ zoneh /= (60 * 60);
+ zonem = (abs(_timezone) / 60) - (zoneh * 60);
+
+ p += sprintf(p, "Date: %s, %02d %s %04d %02d:%02d:%02d %s%02d%02d\r\n",
+ days[tm->tm_wday],
+ tm->tm_mday,
+ months[tm->tm_mon],
+ tm->tm_year + 1900,
+ tm->tm_hour,
+ tm->tm_min,
+ tm->tm_sec,
+ (_timezone > 0) ? "+" : (_timezone < 0) ? "-" : "",
+ zoneh,
+ zonem);
+
+ if(xheaders && strnicmp("From:",xheaders,5)){
+ p += sprintf(p, "From: %s\r\n", RPath);
+ }
+ p += sprintf(p, "Subject: %s\r\n", Subject);
+ p += sprintf(p, "To: %s\r\n", mailTo);
+ if(xheaders){
+ p += sprintf(p, "%s\r\n", xheaders);
+ }
+
+ if ((res = Post(GLOBAL(Buffer))) != SUCCESS)
+ return (res);
+
+ if ((res = Post("\r\n")) != SUCCESS)
+ return (res);
+
+ return (SUCCESS);
+}
+
+
+
+//********************************************************************
+// Name: MailConnect
+// Input: None
+// Output: None
+// Description: Connect to the mail host and receive the welcome message.
+// Author/Date: jcar 20/9/96
+// History:
+//********************************************************************
+int MailConnect()
+{
+
+ int res;
+ TLS_VARS;
+
+
+ // Create Socket
+ if ((GLOBAL(sc) = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+ return (FAILED_TO_OBTAIN_SOCKET_HANDLE);
+
+ // Get our own host name
+ if (gethostname(GLOBAL(LocalHost), HOST_NAME_LEN))
+ return (FAILED_TO_GET_HOSTNAME);
+
+ // Resolve the servers IP
+ //if (!isdigit(GLOBAL(MailHost)[0])||!gethostbyname(GLOBAL(MailHost)))
+ //{
+ // return (FAILED_TO_RESOLVE_HOST);
+ //}
+
+ // Connect to server
+ GLOBAL(sock_in).sin_family = AF_INET;
+ GLOBAL(sock_in).sin_port = htons(25);
+ GLOBAL(sock_in).sin_addr.S_un.S_addr = GetAddr(GLOBAL(MailHost));
+
+ if (connect(GLOBAL(sc), (LPSOCKADDR) & GLOBAL(sock_in), sizeof(GLOBAL(sock_in))))
+ return (FAILED_TO_CONNECT);
+
+ // receive Server welcome message
+ res = Ack();
+ return (res);
+}
+
+
+
+
+
+
+//********************************************************************
+// Name: Post
+// Input:
+// Output:
+// Description:
+// Author/Date: jcar 20/9/96
+// History:
+//********************************************************************
+int Post(LPCSTR msg)
+{
+ int len = strlen(msg);
+ int slen;
+ int index = 0;
+ TLS_VARS;
+
+ while (len > 0) {
+ if ((slen = send(GLOBAL(sc), msg + index, len, 0)) < 1)
+ return (FAILED_TO_SEND);
+ len -= slen;
+ index += slen;
+ }
+ return (SUCCESS);
+}
+
+
+
+//********************************************************************
+// Name: Ack
+// Input:
+// Output:
+// Description:
+// Get the response from the server. We only want to know if the
+// last command was successful.
+// Author/Date: jcar 20/9/96
+// History:
+//********************************************************************
+int Ack()
+{
+ static char *buf;
+ int rlen;
+ int Index = 0;
+ int Received = 0;
+ TLS_VARS;
+
+ if (!buf)
+ if ((buf = (char *) malloc(1024 * 4)) == NULL)
+ return (OUT_OF_MEMORY);
+
+ again:
+
+ if ((rlen = recv(GLOBAL(sc), buf + Index, ((1024 * 4) - 1) - Received, 0)) < 1)
+ return (FAILED_TO_RECEIVE);
+
+ Received += rlen;
+ buf[Received] = 0;
+ //err_msg fprintf(stderr,"Received: (%d bytes) %s", rlen, buf + Index);
+
+ // Check for newline
+ Index += rlen;
+ if ((buf[Received - 2] != '\r') || (buf[Received - 1] != '\n'))
+ // err_msg fprintf(stderr,"Incomplete server message. Awaiting CRLF\n");
+ goto again; // Incomplete data. Line must be terminated by CRLF
+
+ if (buf[0] > '3')
+ return (SMTP_SERVER_ERROR);
+
+ return (SUCCESS);
+}
+
+
+//********************************************************************
+// Name: unsigned long GetAddr (LPSTR szHost)
+// Input:
+// Output:
+// Description: Given a string, it will return an IP address.
+// - first it tries to convert the string directly
+// - if that fails, it tries o resolve it as a hostname
+//
+// WARNING: gethostbyname() is a blocking function
+// Author/Date: jcar 20/9/96
+// History:
+//********************************************************************
+unsigned long GetAddr(LPSTR szHost)
+{
+ LPHOSTENT lpstHost;
+ u_long lAddr = INADDR_ANY;
+
+ /* check that we have a string */
+ if (*szHost) {
+
+ /* check for a dotted-IP address string */
+ lAddr = inet_addr(szHost);
+
+ /* If not an address, then try to resolve it as a hostname */
+ if ((lAddr == INADDR_NONE) && (strcmp(szHost, "255.255.255.255"))) {
+
+ lpstHost = gethostbyname(szHost);
+ if (lpstHost) { /* success */
+ lAddr = *((u_long FAR *) (lpstHost->h_addr));
+ } else {
+ lAddr = INADDR_ANY; /* failure */
+ }
+ }
+ }
+ return (lAddr);
+} /* end GetAddr() */
diff --git a/win32/sendmail.h b/win32/sendmail.h
new file mode 100644
index 0000000000..3c426fb219
--- /dev/null
+++ b/win32/sendmail.h
@@ -0,0 +1,46 @@
+#if !defined(sendmail_h) // Sentry, use file only if it's not already included.
+#define sendmail_h
+#include <windows.h>
+
+#define HOST_NAME_LEN 256
+#define MAX_APPNAME_LENGHT 100
+#define MAX_ERROR_INDEX 17
+#define MIN_ERROR_INDEX 0
+#define MAIL_BUFFER_SIZE (1024*4) // 4k buffer
+// Return values
+#define SUCCESS 0
+#define FAILED_TO_PARSE_ARGUMENTS 1
+#define FAILED_TO_OPEN_MAILFILE 2
+#define FAILED_TO_START_SOCKETS 3
+#define FAILED_TO_RESOLVE_HOST 4
+#define FAILED_TO_OBTAIN_SOCKET_HANDLE 5
+#define FAILED_TO_CONNECT 6
+#define FAILED_TO_SEND 7
+#define FAILED_TO_RECEIVE 8
+#define SMTP_SERVER_ERROR 9
+#define FAILED_TO_GET_HOSTNAME 10
+#define OUT_OF_MEMORY 11
+#define UNKNOWN_ERROR 12
+#define BAD_MSG_CONTENTS 13
+#define BAD_MSG_SUBJECT 14
+#define BAD_MSG_DESTINATION 15
+#define BAD_MSG_RPATH 16
+#define BAD_MAIL_HOST 17
+#define BAD_MSG_FILE 18
+
+
+int TSendMail(char *smtpaddr, int *returnerror,
+ char *RPath, char *Subject, char *mailTo, char *data);
+void TSMClose(void);
+int SendText(char *RPath, char *Subject, char *mailTo, char *data, char *headers);
+char *GetSMErrorText(int index);
+
+int MailConnect();
+int PostHeader(char *, char *, char *, char *);
+int Post(LPCSTR);
+int Ack();
+unsigned long GetAddr(LPSTR szHost);
+
+
+
+#endif // sendmail_h
diff --git a/win32/signal.h b/win32/signal.h
new file mode 100644
index 0000000000..58941d4793
--- /dev/null
+++ b/win32/signal.h
@@ -0,0 +1,4 @@
+#include <signal.h>
+#define SIGALRM 13
+#define SIGVTALRM 26 /* virtual time alarm */
+#define SIGPROF 27 /* profiling time alarm */
diff --git a/win32/syslog.h b/win32/syslog.h
new file mode 100644
index 0000000000..22239fb4e5
--- /dev/null
+++ b/win32/syslog.h
@@ -0,0 +1,73 @@
+/*
+ * This header borrowed from Cygnus GNUwin32 project
+ *
+ * Modified for use with functions to map syslog
+ * calls to EventLog calls on the windows platform
+ *
+ * much of this is not used, but here for the sake of
+ * error free compilation. EventLogs will most likely
+ * not behave as syslog does, but may be useful anyway.
+ * much of what syslog does can be emulated here, but
+ * that will have to be done later.
+ */
+
+#ifndef _SYS_LOG_H
+#define _SYS_LOG_H
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#define LOG_EMERG 1
+#define LOG_ALERT 1
+#define LOG_CRIT 1
+#define LOG_ERR 4
+#define LOG_WARNING 5
+#define LOG_NOTICE 6
+#define LOG_INFO 6
+#define LOG_DEBUG 6
+
+#define LOG_PRIMASK 0x07
+
+#define LOG_PRI(p) ((p) & LOG_PRIMASK)
+#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
+
+#define LOG_KERN (0<<3)
+#define LOG_USER (1<<3)
+#define LOG_MAIL (2<<3)
+#define LOG_DAEMON (3<<3)
+#define LOG_AUTH (4<<3)
+#define LOG_SYSLOG (5<<3)
+#define LOG_LPR (6<<3)
+#define LOG_NEWS (7<<3)
+#define LOG_UUCP (8<<3)
+#define LOG_CRON (9<<3)
+#define LOG_AUTHPRIV (10<<3)
+
+#define LOG_NFACILITIES 10
+#define LOG_FACMASK 0x03f8
+#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
+
+#define LOG_MASK(pri) (1 << (pri))
+#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1)
+
+/*
+ * Option flags for openlog.
+ *
+ * LOG_ODELAY no longer does anything.
+ * LOG_NDELAY is the inverse of what it used to be.
+ */
+#define LOG_PID 0x01 /* log the pid with each message */
+#define LOG_CONS 0x02 /* log on the console if errors in sending */
+#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */
+#define LOG_NDELAY 0x08 /* don't delay open */
+#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */
+#define LOG_PERROR 0x20 /* log to stderr as well */
+
+
+extern void closelog(void);
+extern void openlog(const char *, int, int);
+// setlogmask not implemented
+//extern int setlogmask (int);
+extern void syslog(int, const char *,...);
+
+
+#endif /* _SYS_LOG_H */
diff --git a/win32/time.c b/win32/time.c
new file mode 100644
index 0000000000..1a50f87547
--- /dev/null
+++ b/win32/time.c
@@ -0,0 +1,156 @@
+
+/*****************************************************************************
+ * *
+ * DH_TIME.C *
+ * *
+ * Freely redistributable and modifiable. Use at your own risk. *
+ * *
+ * Copyright 1994 The Downhill Project *
+ *
+ * Modified by Shane Caraveo for use with PHP
+ *
+ *****************************************************************************/
+
+
+/* Include stuff ************************************************************ */
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include "time.h"
+#include "unistd.h"
+#include "signal.h"
+#include <winbase.h>
+#include <mmsystem.h>
+#include <errno.h>
+
+int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
+{
+ _int64 mstimer, freq;
+ /* Get the time, if they want it */
+ if (time_Info != NULL) {
+ time_Info->tv_sec = time(NULL);
+ /* get ticks-per-second of the performance counter
+ Note the necessary typecast to a LARGE_INTEGER structure
+ */
+ if (!QueryPerformanceFrequency((LARGE_INTEGER *) & freq)) {
+ time_Info->tv_usec = 0;
+ } else {
+ QueryPerformanceCounter((LARGE_INTEGER *) & mstimer);
+ mstimer = (__int64) (mstimer * .8);
+ time_Info->tv_usec = (long) (mstimer % 0x0FFFFFFF);
+ }
+ }
+ /* Get the timezone, if they want it */
+ if (timezone_Info != NULL) {
+ _tzset();
+ timezone_Info->tz_minuteswest = _timezone;
+ timezone_Info->tz_dsttime = _daylight;
+ }
+ /* And return */
+ return 0;
+}
+
+
+/* this usleep isnt exactly accurate but should do ok */
+void usleep(unsigned int useconds)
+{
+ __int64 mstimer, freq;
+ long now, then;
+ if (QueryPerformanceFrequency((LARGE_INTEGER *) & freq)) {
+ QueryPerformanceCounter((LARGE_INTEGER *) & mstimer);
+ now = (long) (((__int64) (mstimer * .8)) % 0x0FFFFFFF);
+ then = now + useconds;
+ while (now < then) {
+ QueryPerformanceCounter((LARGE_INTEGER *) & mstimer);
+ now = (long) (((__int64) (mstimer * .8)) % 0x0FFFFFFF);
+ }
+ } else {
+ /*workaround for systems without performance counter
+ this is actualy a millisecond sleep */
+ Sleep((int) (useconds / 1000));
+ }
+}
+
+
+#if HAVE_SETITIMER
+
+
+#ifndef THREAD_SAFE
+unsigned int proftimer, virttimer, realtimer;
+extern LPMSG phpmsg;
+#endif
+
+struct timer_msg {
+ int signal;
+ unsigned int threadid;
+};
+
+
+LPTIMECALLBACK setitimer_timeout(UINT uTimerID, UINT info, DWORD dwUser, DWORD dw1, DWORD dw2)
+{
+ struct timer_msg *msg = (struct timer_msg *) info;
+
+ if (msg) {
+ raise((int) msg->signal);
+ PostThreadMessage(msg->threadid,
+ WM_NOTIFY, msg->signal, 0);
+ free(msg);
+ }
+ return 0;
+}
+
+int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
+{
+ int timeout = value->it_value.tv_sec * 1000 + value->it_value.tv_usec;
+ int repeat = TIME_ONESHOT;
+ TLS_VARS;
+
+ /*make sure the message queue is initialized */
+ PeekMessage(GLOBAL(phpmsg), NULL, WM_USER, WM_USER, PM_NOREMOVE);
+ if (timeout > 0) {
+ struct timer_msg *msg = malloc(sizeof(struct timer_msg));
+ msg->threadid = GetCurrentThreadId();
+ if (!ovalue) {
+ repeat = TIME_PERIODIC;
+ }
+ switch (which) {
+ case ITIMER_REAL:
+ msg->signal = SIGALRM;
+ GLOBAL(realtimer) = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
+ break;
+ case ITIMER_VIRT:
+ msg->signal = SIGVTALRM;
+ GLOBAL(virttimer) = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
+ break;
+ case ITIMER_PROF:
+ msg->signal = SIGPROF;
+ GLOBAL(proftimer) = timeSetEvent(timeout, 100, (LPTIMECALLBACK) setitimer_timeout, (UINT) msg, repeat);
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ break;
+ }
+ } else {
+ switch (which) {
+ case ITIMER_REAL:
+ timeKillEvent(GLOBAL(realtimer));
+ break;
+ case ITIMER_VIRT:
+ timeKillEvent(GLOBAL(virttimer));
+ break;
+ case ITIMER_PROF:
+ timeKillEvent(GLOBAL(proftimer));
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ break;
+ }
+ }
+
+
+ return 0;
+}
+
+#endif
diff --git a/win32/time.h b/win32/time.h
new file mode 100644
index 0000000000..e5abd293c3
--- /dev/null
+++ b/win32/time.h
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * *
+ * sys/time.h *
+ * *
+ * Freely redistributable and modifiable. Use at your own risk. *
+ * *
+ * Copyright 1994 The Downhill Project *
+ *
+ * Modified by Shane Caraveo for PHP
+ *
+ *****************************************************************************/
+
+
+/* Include stuff ************************************************************ */
+#include <winsock.h>
+#include <time.h>
+
+/* Struct stuff ************************************************************* */
+struct timezone {
+ int tz_minuteswest;
+ int tz_dsttime;
+};
+
+
+struct itimerval {
+ struct timeval it_interval; /* next value */
+ struct timeval it_value; /* current value */
+};
+
+#define ITIMER_REAL 0 /*generates sigalrm */
+#define ITIMER_VIRTUAL 1 /*generates sigvtalrm */
+#define ITIMER_VIRT 1 /*generates sigvtalrm */
+#define ITIMER_PROF 2 /*generates sigprof */
+
+/* Prototype stuff ********************************************************** */
+extern int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info);
+
+/* setitimer operates at 100 millisecond resolution */
+extern int setitimer(int which, const struct itimerval *value,
+ struct itimerval *ovalue);
diff --git a/win32/unistd.h b/win32/unistd.h
new file mode 100644
index 0000000000..5604103ec9
--- /dev/null
+++ b/win32/unistd.h
@@ -0,0 +1 @@
+extern void usleep(unsigned int useconds);
diff --git a/win32/wfile.c b/win32/wfile.c
new file mode 100644
index 0000000000..1407d6a32b
--- /dev/null
+++ b/win32/wfile.c
@@ -0,0 +1,17 @@
+
+/* Function borrowed from the Downhill Project */
+#include "wfile.h"
+#include "direct.h"
+
+int readlink(char *file_Name, char *buf_Mem, int buf_Size)
+{
+ /* See if the file exists */
+ if (access(file_Name, X_OK) == -1) {
+ errno = ENOENT;
+ } else {
+ errno = EINVAL;
+ }
+
+ /* Either way, it's not a link */
+ return -1;
+}
diff --git a/win32/wfile.h b/win32/wfile.h
new file mode 100644
index 0000000000..2e79406478
--- /dev/null
+++ b/win32/wfile.h
@@ -0,0 +1,16 @@
+#include <io.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define access _access
+#define X_OK 0
+#ifndef ENOENT
+#define ENOENT 136
+#endif
+#ifndef EINVAL
+#define EINVAL 131
+#endif
+
+int readlink(char *, char *, int);
+int checkroot(char *path);
diff --git a/win32/winutil.c b/win32/winutil.c
new file mode 100644
index 0000000000..0ac7e54703
--- /dev/null
+++ b/win32/winutil.c
@@ -0,0 +1,29 @@
+#ifdef THREAD_SAFE
+#include "tls.h"
+#else
+#define TLS_VARS
+#define GLOBAL(a) a
+#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include "winutil.h"
+
+#ifndef THREAD_SAFE
+static char Win_Error_msg[256];
+#endif
+
+char *php3_win_err(void)
+{
+ TLS_VARS;
+
+ FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) GLOBAL(Win_Error_msg),
+ 256,
+ NULL);
+
+ return GLOBAL(Win_Error_msg);
+}
diff --git a/win32/winutil.h b/win32/winutil.h
new file mode 100644
index 0000000000..ca6c63a245
--- /dev/null
+++ b/win32/winutil.h
@@ -0,0 +1 @@
+extern char *php3_win_err(void);
diff --git a/win32/wsyslog.c b/win32/wsyslog.c
new file mode 100644
index 0000000000..4207370dbf
--- /dev/null
+++ b/win32/wsyslog.c
@@ -0,0 +1,128 @@
+/*
+ * This file modified from sources for imap4 for use
+ * in PHP 3
+ */
+/*
+ * Program: Unix compatibility routines
+ *
+ * Author: Mark Crispin
+ * Networks and Distributed Computing
+ * Computing & Communications
+ * University of Washington
+ * Administration Building, AG-44
+ * Seattle, WA 98195
+ * Internet: MRC@CAC.Washington.EDU
+ *
+ * Date: 14 September 1996
+ * Last Edited: 22 October 1996
+ *
+ * Copyright 1996 by the University of Washington
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appears in all copies and that both the
+ * above copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the University of Washington not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. This software is made available
+ * "as is", and
+ * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+ * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
+ * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+
+/* DEDICATION
+
+ * This file is dedicated to my dog, Unix, also known as Yun-chan and
+ * Unix J. Terwilliker Jehosophat Aloysius Monstrosity Animal Beast. Unix
+ * passed away at the age of 11 1/2 on September 14, 1996, 12:18 PM PDT, after
+ * a two-month bout with cirrhosis of the liver.
+ *
+ * He was a dear friend, and I miss him terribly.
+ *
+ * Lift a leg, Yunie. Luv ya forever!!!!
+ */
+
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include "php.h" /*php specific */
+#include "syslog.h"
+#include <stdio.h>
+#include <fcntl.h>
+#include <process.h>
+
+#ifndef THREAD_SAFE
+static char *loghdr; /* log file header string */
+static HANDLE loghdl = NULL; /* handle of event source */
+#endif
+
+void closelog(void)
+{
+ TLS_VARS;
+ DeregisterEventSource(GLOBAL(loghdl));
+ efree(GLOBAL(loghdr));
+}
+
+/* Emulator for BSD syslog() routine
+ * Accepts: priority
+ * message
+ * parameters
+ */
+
+void syslog(int priority, const char *message,...)
+{
+ va_list args;
+ LPTSTR strs[2];
+ char tmp[1024]; /* callers must be careful not to pop this */
+ unsigned short etype;
+ TLS_VARS;
+
+ /* default event source */
+ if (!GLOBAL(loghdl))
+ openlog("c-client", LOG_PID, LOG_MAIL);
+ switch (priority) { /* translate UNIX type into NT type */
+ case LOG_ALERT:
+ etype = EVENTLOG_ERROR_TYPE;
+ break;
+ case LOG_INFO:
+ etype = EVENTLOG_INFORMATION_TYPE;
+ break;
+ default:
+ etype = EVENTLOG_WARNING_TYPE;
+ }
+ va_start(args, message); /* initialize vararg mechanism */
+ vsprintf(tmp, message, args); /* build message */
+ strs[0] = GLOBAL(loghdr); /* write header */
+ strs[1] = tmp; /* then the message */
+ /* report the event */
+ ReportEvent(GLOBAL(loghdl), etype, (unsigned short) priority, 2000, NULL, 2, 0, strs, NULL);
+ va_end(args);
+}
+
+
+/* Emulator for BSD openlog() routine
+ * Accepts: identity
+ * options
+ * facility
+ */
+
+void openlog(const char *ident, int logopt, int facility)
+{
+ char tmp[1024];
+ TLS_VARS;
+
+ if (GLOBAL(loghdl)) {
+ closelog();
+ }
+ GLOBAL(loghdl) = RegisterEventSource(NULL, ident);
+ sprintf(tmp, (logopt & LOG_PID) ? "%s[%d]" : "%s", ident, getpid());
+ GLOBAL(loghdr) = estrdup(tmp); /* save header for later */
+}