diff options
author | Zeev Suraski <zeev@php.net> | 1999-04-07 21:05:13 +0000 |
---|---|---|
committer | Zeev Suraski <zeev@php.net> | 1999-04-07 21:05:13 +0000 |
commit | aceaabceffd537a0ed83fa25e189b08eae585f4a (patch) | |
tree | bcef55f16a2ae57c1c883b34347f9e6906ca6dfe /win32 | |
parent | d94f3e22ae6fe17d82b189dc362e975a906f919a (diff) | |
download | php-git-aceaabceffd537a0ed83fa25e189b08eae585f4a.tar.gz |
PHP 4.0
Diffstat (limited to 'win32')
-rw-r--r-- | win32/flock.c | 83 | ||||
-rw-r--r-- | win32/flock.h | 11 | ||||
-rw-r--r-- | win32/grp.h | 31 | ||||
-rw-r--r-- | win32/param.h | 16 | ||||
-rw-r--r-- | win32/pwd.c | 79 | ||||
-rw-r--r-- | win32/pwd.h | 57 | ||||
-rw-r--r-- | win32/readdir.c | 111 | ||||
-rw-r--r-- | win32/readdir.h | 37 | ||||
-rw-r--r-- | win32/sendmail.c | 511 | ||||
-rw-r--r-- | win32/sendmail.h | 46 | ||||
-rw-r--r-- | win32/signal.h | 4 | ||||
-rw-r--r-- | win32/syslog.h | 73 | ||||
-rw-r--r-- | win32/time.c | 156 | ||||
-rw-r--r-- | win32/time.h | 40 | ||||
-rw-r--r-- | win32/unistd.h | 1 | ||||
-rw-r--r-- | win32/wfile.c | 17 | ||||
-rw-r--r-- | win32/wfile.h | 16 | ||||
-rw-r--r-- | win32/winutil.c | 29 | ||||
-rw-r--r-- | win32/winutil.h | 1 | ||||
-rw-r--r-- | win32/wsyslog.c | 128 |
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 */ +} |