You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by Ben Laurie <be...@hyperreal.com> on 1997/06/15 21:22:56 UTC
cvs commit: apache/src/regex regex.mak
ben 97/06/15 12:22:54
Modified: src .cvsignore alloc.c alloc.h buff.c buff.h conf.h
http_conf_globals.h http_core.c http_log.c
http_main.c http_main.h http_protocol.c
http_request.c httpd.h mod_alias.c mod_cgi.c
mod_dir.c mod_include.c mod_info.c mod_log_agent.c
mod_log_config.c mod_log_referer.c
mod_negotiation.c mod_rewrite.c mod_rewrite.h
mod_userdir.c rfc1413.c scoreboard.h util.c
util_script.c util_script.h
src/modules/proxy mod_proxy.c mod_proxy.h proxy_cache.c
proxy_connect.c proxy_ftp.c proxy_http.c
proxy_util.c
Added: . README.NT
src apache.mak multithread.h
src/modules/proxy proxy.mak
src/nt getopt.c getopt.h modules.c multithread.c
readdir.c readdir.h service.c service.h
src/regex regex.mak
Log:
Initial NT support.
Reviewed by: Ben
Submitted by: Ambarish Malpani <am...@valicert.com> (integrated by Ben Laurie <be...@algroup.co.uk>)
Revision Changes Path
1.3 +3 -0 apache/src/.cvsignore
Index: .cvsignore
===================================================================
RCS file: /export/home/cvs/apache/src/.cvsignore,v
retrieving revision 1.2
retrieving revision 1.3
diff -C3 -r1.2 -r1.3
*** .cvsignore 1997/02/18 05:29:29 1.2
--- .cvsignore 1997/06/15 19:22:23 1.3
***************
*** 3,5 ****
--- 3,8 ----
modules.c
httpd
Makefile.config
+ apache.mdp
+ apache.ncb
+ Release
1.29 +207 -8 apache/src/alloc.c
Index: alloc.c
===================================================================
RCS file: /export/home/cvs/apache/src/alloc.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -C3 -r1.28 -r1.29
*** alloc.c 1997/05/27 04:14:20 1.28
--- alloc.c 1997/06/15 19:22:23 1.29
***************
*** 60,67 ****
--- 60,69 ----
#include "conf.h"
#include "alloc.h"
+ #include "multithread.h"
#include <stdarg.h>
+ #include <assert.h>
/*****************************************************************
*
***************
*** 97,103 ****
};
union block_hdr *block_freelist = NULL;
!
/* Get a completely new block from the system pool. Note that we rely on
--- 99,106 ----
};
union block_hdr *block_freelist = NULL;
! mutex *alloc_mutex = NULL;
! mutex *spawn_mutex = NULL;
/* Get a completely new block from the system pool. Note that we rely on
***************
*** 143,152 ****
* in the chain to point to the free blocks we already had.
*/
! union block_hdr *old_free_list = block_freelist;
if (blok == NULL) return; /* Sanity check --- freeing empty pool? */
block_freelist = blok;
/*
--- 146,157 ----
* in the chain to point to the free blocks we already had.
*/
! union block_hdr *old_free_list;
if (blok == NULL) return; /* Sanity check --- freeing empty pool? */
+ acquire_mutex(alloc_mutex);
+ old_free_list = block_freelist;
block_freelist = blok;
/*
***************
*** 167,172 ****
--- 172,178 ----
/* Finally, reset next pointer to get the old free blocks back */
blok->h.next = old_free_list;
+ release_mutex(alloc_mutex);
}
***************
*** 264,269 ****
--- 270,277 ----
pool *new_pool;
block_alarms();
+
+ acquire_mutex(alloc_mutex);
blok = new_block (0);
new_pool = (pool *)blok->h.first_avail;
***************
*** 280,291 ****
p->sub_pools = new_pool;
}
unblock_alarms();
return new_pool;
}
! void init_alloc() { permanent_pool = make_sub_pool (NULL); }
void clear_pool (struct pool *a)
{
--- 288,305 ----
p->sub_pools = new_pool;
}
+ release_mutex(alloc_mutex);
unblock_alarms();
return new_pool;
}
! void init_alloc()
! {
! alloc_mutex = create_mutex(NULL);
! spawn_mutex = create_mutex(NULL);
! permanent_pool = make_sub_pool (NULL);
! }
void clear_pool (struct pool *a)
{
***************
*** 359,367 ****
--- 373,387 ----
/* Nope --- get a new one that's guaranteed to be big enough */
block_alarms();
+
+ acquire_mutex(alloc_mutex);
+
blok = new_block (size);
a->last->h.next = blok;
a->last = blok;
+
+ release_mutex(alloc_mutex);
+
unblock_alarms();
first_avail = blok->h.first_avail;
***************
*** 771,779 ****
--- 791,810 ----
void cleanup_for_exec()
{
+ #ifndef WIN32
+ /*
+ * Don't need to do anything on NT, because I
+ * am actually going to spawn the new process - not
+ * exec it. All handles that are not inheritable, will
+ * be automajically closed. The only problem is with
+ * file handles that are open, but there isn't much
+ * I can do about that (except if the child decides
+ * to go out and close them
+ */
block_alarms();
cleanup_pool_for_exec (permanent_pool);
unblock_alarms();
+ #endif /* ndef WIN32 */
}
/*****************************************************************
***************
*** 837,842 ****
--- 868,880 ----
{
FILE *fd = NULL;
int baseFlag, desc;
+ int modeFlags = 0;
+
+ #ifdef WIN32
+ modeFlags = _S_IREAD | _S_IWRITE;
+ #else
+ modeFlags = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ #endif
block_alarms();
***************
*** 844,850 ****
/* Work around faulty implementations of fopen */
baseFlag = (*(mode+1) == '+') ? O_RDWR : O_WRONLY;
desc = open(name, baseFlag | O_APPEND | O_CREAT,
! S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (desc >= 0) {
fd = fdopen(desc, mode);
}
--- 882,888 ----
/* Work around faulty implementations of fopen */
baseFlag = (*(mode+1) == '+') ? O_RDWR : O_WRONLY;
desc = open(name, baseFlag | O_APPEND | O_CREAT,
! modeFlags);
if (desc >= 0) {
fd = fdopen(desc, mode);
}
***************
*** 881,886 ****
--- 919,964 ----
return res;
}
+ /*****************************************************************
+ *
+ * Files and file descriptors; these are just an application of the
+ * generic cleanup interface.
+ */
+
+ static void socket_cleanup (void *fdv)
+ {
+ int rv;
+
+ rv = closesocket((int)fdv);
+ }
+
+ void note_cleanups_for_socket (pool *p, int fd) {
+ register_cleanup (p, (void *)fd, socket_cleanup, socket_cleanup);
+ }
+
+ void kill_cleanups_for_socket(pool *p,int sock)
+ {
+ kill_cleanup(p,(void *)sock,socket_cleanup);
+ }
+
+ int pclosesocket(pool *a, int sock)
+ {
+ int res;
+ int save_errno;
+
+ block_alarms();
+ res = closesocket(sock);
+ #ifdef WIN32
+ errno = WSAGetLastError() - WSABASEERR;
+ #endif /* WIN32 */
+ save_errno = errno;
+ kill_cleanup(a, (void *)sock, socket_cleanup);
+ unblock_alarms();
+ errno = save_errno;
+ return res;
+ }
+
+
/*
* Here's a pool-based interface to POSIX regex's regcomp().
* Note that we return regex_t instead of being passed one.
***************
*** 939,945 ****
a->subprocesses = new;
}
! int spawn_child_err (pool *p, void (*func)(void *), void *data,
enum kill_conditions kill_how,
FILE **pipe_in, FILE **pipe_out, FILE **pipe_err)
{
--- 1017,1029 ----
a->subprocesses = new;
}
! #ifdef WIN32
! #define enc_pipe(fds) _pipe(fds, 512, O_TEXT | O_NOINHERIT)
! #else
! #define enc_pipe(fds) pipe(fds)
! #endif /* WIN32 */
!
! int spawn_child_err (pool *p, int (*func)(void *), void *data,
enum kill_conditions kill_how,
FILE **pipe_in, FILE **pipe_out, FILE **pipe_err)
{
***************
*** 951,957 ****
block_alarms();
! if (pipe_in && pipe (in_fds) < 0)
{
save_errno = errno;
unblock_alarms();
--- 1035,1041 ----
block_alarms();
! if (pipe_in && enc_pipe (in_fds) < 0)
{
save_errno = errno;
unblock_alarms();
***************
*** 959,965 ****
return 0;
}
! if (pipe_out && pipe (out_fds) < 0) {
save_errno = errno;
if (pipe_in) {
close (in_fds[0]); close (in_fds[1]);
--- 1043,1049 ----
return 0;
}
! if (pipe_out && enc_pipe (out_fds) < 0) {
save_errno = errno;
if (pipe_in) {
close (in_fds[0]); close (in_fds[1]);
***************
*** 969,975 ****
return 0;
}
! if (pipe_err && pipe (err_fds) < 0) {
save_errno = errno;
if (pipe_in) {
close (in_fds[0]); close (in_fds[1]);
--- 1053,1059 ----
return 0;
}
! if (pipe_err && enc_pipe (err_fds) < 0) {
save_errno = errno;
if (pipe_in) {
close (in_fds[0]); close (in_fds[1]);
***************
*** 982,987 ****
--- 1066,1151 ----
return 0;
}
+ #ifdef WIN32
+
+ {
+ HANDLE thread_handle;
+ int hStdIn, hStdOut, hStdErr;
+ int old_priority;
+
+ acquire_mutex(spawn_mutex);
+ thread_handle = GetCurrentThread(); /* doesn't need to be closed */
+ old_priority = GetThreadPriority(thread_handle);
+ SetThreadPriority(thread_handle, THREAD_PRIORITY_HIGHEST);
+ /* Now do the right thing with your pipes */
+ if(pipe_in)
+ {
+ hStdIn = dup(fileno(stdin));
+ dup2(in_fds[0], fileno(stdin));
+ close(in_fds[0]);
+ }
+ if(pipe_out)
+ {
+ hStdOut = dup(fileno(stdout));
+ dup2(out_fds[1], fileno(stdout));
+ close(out_fds[1]);
+ }
+ if(pipe_err)
+ {
+ hStdErr = dup(fileno(stderr));
+ dup2(err_fds[1], fileno(stderr));
+ close(err_fds[1]);
+ }
+
+ pid = (*func)(data);
+ if(!pid)
+ {
+ save_errno = errno;
+ close(in_fds[1]);
+ close(out_fds[0]);
+ close(err_fds[0]);
+ }
+
+ /* restore the original stdin, stdout and stderr */
+ if(pipe_in)
+ dup2(hStdIn, fileno(stdin));
+ if(pipe_out)
+ dup2(hStdOut, fileno(stdout));
+ if(pipe_err)
+ dup2(hStdErr, fileno(stderr));
+
+ if(pid)
+ {
+ note_subprocess(p, pid, kill_how);
+ if(pipe_in)
+ {
+ *pipe_in = fdopen(in_fds[1], "wb");
+ if(*pipe_in)
+ note_cleanups_for_file(p, *pipe_in);
+ }
+ if(pipe_out)
+ {
+ *pipe_out = fdopen(out_fds[0], "rb");
+ if(*pipe_out)
+ note_cleanups_for_file(p, *pipe_out);
+ }
+ if(pipe_err)
+ {
+ *pipe_err = fdopen(err_fds[0], "rb");
+ if(*pipe_err)
+ note_cleanups_for_file(p, *pipe_err);
+ }
+ }
+ SetThreadPriority(thread_handle, old_priority);
+ release_mutex(spawn_mutex);
+ /*
+ * go on to the end of the function, where you can
+ * unblock alarms and return the pid
+ */
+
+ }
+ #else
+
if ((pid = fork()) < 0) {
save_errno = errno;
if (pipe_in) {
***************
*** 1065,1070 ****
--- 1229,1235 ----
if (*pipe_err) note_cleanups_for_file (p, *pipe_err);
}
+ #endif /* WIN32 */
unblock_alarms();
return pid;
***************
*** 1089,1095 ****
--- 1254,1293 ----
* don't waste any more cycles doing whatever it is that they shouldn't
* be doing anymore.
*/
+ #ifdef WIN32
+ /* Pick up all defunct processes */
+ for (p = procs; p; p = p->next) {
+ if (GetExitCodeProcess((HANDLE)p->pid, &status)) {
+ p->kill_how = kill_never;
+ }
+ }
+
+ for (p = procs; p; p = p->next) {
+ if (p->kill_how == kill_after_timeout) {
+ need_timeout = 1;
+ } else if (p->kill_how == kill_always) {
+ TerminateProcess((HANDLE)p->pid, 1);
+ }
+ }
+ /* Sleep only if we have to... */
+
+ if (need_timeout) sleep (3);
+
+ /* OK, the scripts we just timed out for have had a chance to clean up
+ * --- now, just get rid of them, and also clean up the system accounting
+ * goop...
+ */
+
+ for (p = procs; p; p = p->next){
+ if (p->kill_how == kill_after_timeout)
+ TerminateProcess((HANDLE)p->pid, 1);
+ }
+
+ for (p = procs; p; p = p->next){
+ CloseHandle((HANDLE)p->pid);
+ }
+ #else
#ifndef NEED_WAITPID
/* Pick up all defunct processes */
for (p = procs; p; p = p->next) {
***************
*** 1126,1130 ****
--- 1324,1329 ----
if (p->kill_how != kill_never)
waitpid (p->pid, &status, 0);
}
+ #endif /* WIN32 */
}
1.22 +5 -1 apache/src/alloc.h
Index: alloc.h
===================================================================
RCS file: /export/home/cvs/apache/src/alloc.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -C3 -r1.21 -r1.22
*** alloc.h 1997/05/27 04:14:19 1.21
--- alloc.h 1997/06/15 19:22:23 1.22
***************
*** 213,218 ****
--- 213,222 ----
void note_cleanups_for_fd (pool *, int);
void kill_cleanups_for_fd (pool *p, int fd);
+ void note_cleanups_for_socket (pool *, int);
+ void kill_cleanups_for_socket (pool *p, int sock);
+ int pclosesocket(pool *a, int sock);
+
regex_t *pregcomp (pool *p, const char *pattern, int cflags);
void pregfree (pool *p, regex_t *reg);
***************
*** 235,241 ****
enum kill_conditions { kill_never, kill_always, kill_after_timeout, just_wait};
! int spawn_child_err (pool *, void (*)(void *), void *,
enum kill_conditions, FILE **pipe_in, FILE **pipe_out,
FILE **pipe_err);
#define spawn_child(p,f,v,k,in,out) spawn_child_err(p,f,v,k,in,out,NULL)
--- 239,245 ----
enum kill_conditions { kill_never, kill_always, kill_after_timeout, just_wait};
! int spawn_child_err (pool *, int (*)(void *), void *,
enum kill_conditions, FILE **pipe_in, FILE **pipe_out,
FILE **pipe_err);
#define spawn_child(p,f,v,k,in,out) spawn_child_err(p,f,v,k,in,out,NULL)
1.27 +174 -14 apache/src/buff.c
Index: buff.c
===================================================================
RCS file: /export/home/cvs/apache/src/buff.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -C3 -r1.26 -r1.27
*** buff.c 1997/05/29 05:21:15 1.26
--- buff.c 1997/06/15 19:22:24 1.27
***************
*** 72,77 ****
--- 72,79 ----
#define DEFAULT_BUFSIZE (4096)
+ extern int check_alarm(); /* didn't want to include http_main.h */
+
/*
* Buffered I/O routines.
* These are a replacement for the stdio routines.
***************
*** 96,101 ****
--- 98,199 ----
* futher I/O will be done
*/
+ #ifdef WIN32
+ #include <assert.h>
+
+ int
+ sendwithtimeout(int sock, const char *buf, int len, int flags)
+ {
+ int iostate = 1;
+ fd_set fdset;
+ struct timeval tv;
+ int err = WSAEWOULDBLOCK;
+ int rv;
+
+ if(!(tv.tv_sec = check_alarm()))
+ return(send(sock, buf, len, flags));
+
+ rv = ioctlsocket(sock, FIONBIO, &iostate);
+ iostate = 0;
+ if(rv)
+ {
+ err = WSAGetLastError();
+ assert(0);
+ }
+ rv = send(sock, buf, len, flags);
+ if(rv == SOCKET_ERROR)
+ {
+ err = WSAGetLastError();
+ if(err == WSAEWOULDBLOCK)
+ {
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+ tv.tv_usec = 0;
+ rv = select(FD_SETSIZE, NULL, &fdset, NULL, &tv);
+ if(rv == 0)
+ {
+ ioctlsocket(sock, FIONBIO, &iostate);
+ check_alarm();
+ WSASetLastError(WSAEWOULDBLOCK);
+ return(SOCKET_ERROR);
+ }
+ rv = send(sock, buf, len, flags);
+ if(rv == SOCKET_ERROR)
+ err = WSAGetLastError();
+ }
+ }
+ ioctlsocket(sock, FIONBIO, &iostate);
+ if(rv == SOCKET_ERROR)
+ WSASetLastError(err);
+ return(rv);
+ }
+
+
+ int
+ recvwithtimeout(int sock, char *buf, int len, int flags)
+ {
+ int iostate = 1;
+ fd_set fdset;
+ struct timeval tv;
+ int err = WSAEWOULDBLOCK;
+ int rv;
+
+ if(!(tv.tv_sec = check_alarm()))
+ return(recv(sock, buf, len, flags));
+
+ rv = ioctlsocket(sock, FIONBIO, &iostate);
+ iostate = 0;
+ assert(!rv);
+ rv = recv(sock, buf, len, flags);
+ if(rv == SOCKET_ERROR)
+ {
+ err = WSAGetLastError();
+ if(err == WSAEWOULDBLOCK)
+ {
+ FD_ZERO(&fdset);
+ FD_SET(sock, &fdset);
+ tv.tv_usec = 0;
+ rv = select(FD_SETSIZE, &fdset, NULL, NULL, &tv);
+ if(rv == 0)
+ {
+ ioctlsocket(sock, FIONBIO, &iostate);
+ check_alarm();
+ WSASetLastError(WSAEWOULDBLOCK);
+ return(SOCKET_ERROR);
+ }
+ rv = recv(sock, buf, len, flags);
+ if(rv == SOCKET_ERROR)
+ err = WSAGetLastError();
+ }
+ }
+ ioctlsocket(sock, FIONBIO, &iostate);
+ if(rv == SOCKET_ERROR)
+ WSASetLastError(err);
+ return(rv);
+ }
+
+ #endif /* WIN32 */
+
static void
doerror(BUFF *fb, int err)
{
***************
*** 115,121 ****
* Create a new buffered stream
*/
BUFF *
! bcreate(pool *p, int flags)
{
BUFF *fb;
--- 213,219 ----
* Create a new buffered stream
*/
BUFF *
! bcreate(pool *p, int flags, int is_socket)
{
BUFF *fb;
***************
*** 142,147 ****
--- 240,246 ----
fb->fd = -1;
fb->fd_in = -1;
+ fb->is_socket = is_socket;
return fb;
}
***************
*** 324,330 ****
--- 423,440 ----
}
}
do {
+ #ifdef WIN32
+ if(fb->is_socket)
+ {
+ rv = recvwithtimeout( fb->fd_in, buf, nbyte, 0 );
+ if(rv == SOCKET_ERROR)
+ errno = WSAGetLastError() - WSABASEERR;
+ }
+ else
+ rv = read( fb->fd_in, buf, nbyte );
+ #else
rv = read( fb->fd_in, buf, nbyte );
+ #endif /* WIN32 */
} while (rv == -1 && errno == EINTR && !(fb->flags & B_EOUT));
return( rv );
}
***************
*** 621,629 ****
return -1;
while (nbyte > 0) {
! i = write(fb->fd, buf, nbyte);
! if (i < 0) {
! if (errno != EAGAIN && errno != EINTR) {
return -1;
}
}
--- 731,750 ----
return -1;
while (nbyte > 0) {
! #ifdef WIN32
! if(fb->is_socket)
! {
! i = sendwithtimeout( fb->fd, buf, nbyte, 0);
! if(i == SOCKET_ERROR)
! errno = WSAGetLastError() - WSABASEERR;
! }
! else
! i = write( fb->fd, buf, nbyte );
! #else
! i = write( fb->fd, buf, nbyte );
! #endif /* WIN32 */
! if( i < 0 ) {
! if( errno != EAGAIN && errno != EINTR ) {
return -1;
}
}
***************
*** 648,663 ****
bcwrite(BUFF *fb, const void *buf, int nbyte)
{
char chunksize[16]; /* Big enough for practically anything */
#ifndef NO_WRITEV
struct iovec vec[3];
! int i, rv;
#endif
if (fb->flags & (B_WRERR|B_EOUT))
return -1;
if (!(fb->flags & B_CHUNK))
! return write(fb->fd, buf, nbyte);
#ifdef NO_WRITEV
/* without writev() this has poor performance, too bad */
--- 769,799 ----
bcwrite(BUFF *fb, const void *buf, int nbyte)
{
char chunksize[16]; /* Big enough for practically anything */
+ int i;
#ifndef NO_WRITEV
struct iovec vec[3];
! int rv;
#endif
if (fb->flags & (B_WRERR|B_EOUT))
return -1;
if (!(fb->flags & B_CHUNK))
! {
! #ifdef WIN32
! if(fb->is_socket)
! {
! i = sendwithtimeout(fb->fd, buf, nbyte, 0 );
! if(i == SOCKET_ERROR)
! errno = WSAGetLastError() - WSABASEERR;
! }
! else
! i = write(fb->fd, buf, nbyte);
! #else
! i = write(fb->fd, buf, nbyte);
! #endif /* WIN32 */
! return(i);
! }
#ifdef NO_WRITEV
/* without writev() this has poor performance, too bad */
***************
*** 778,787 ****
*/
i = (write_it_all(fb, fb->outbase, fb->outcnt) == -1) ?
-1 : fb->outcnt;
! }
! else {
! do i = write(fb->fd, fb->outbase, fb->outcnt);
! while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
}
if (i <= 0) {
if (i == 0) /* return of 0 means non-blocking */
--- 914,935 ----
*/
i = (write_it_all(fb, fb->outbase, fb->outcnt) == -1) ?
-1 : fb->outcnt;
! } else {
! do {
! #ifdef WIN32
! if(fb->is_socket)
! {
! i = sendwithtimeout(fb->fd, fb->outbase, fb->outcnt, 0 );
! if(i == SOCKET_ERROR)
! errno = WSAGetLastError() - WSABASEERR;
! }
! else
! i = write(fb->fd, fb->outbase, fb->outcnt);
!
! #else
! i = write(fb->fd, fb->outbase, fb->outcnt);
! #endif /* WIN32 */
! } while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
}
if (i <= 0) {
if (i == 0) /* return of 0 means non-blocking */
***************
*** 862,869 ****
while (fb->outcnt > 0)
{
/* the buffer must be full */
! do i = write(fb->fd, fb->outbase, fb->outcnt);
! while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
if (i == 0) {
errno = EAGAIN;
return -1; /* return of 0 means non-blocking */
--- 1010,1029 ----
while (fb->outcnt > 0)
{
/* the buffer must be full */
! do {
! #ifdef WIN32
! if(fb->is_socket)
! {
! i = sendwithtimeout(fb->fd, fb->outbase, fb->outcnt, 0 );
! if(i == SOCKET_ERROR)
! errno = WSAGetLastError() - WSABASEERR;
! }
! else
! i = write(fb->fd, fb->outbase, fb->outcnt);
! #else
! i = write(fb->fd, fb->outbase, fb->outcnt);
! #endif /* WIN32 */
! } while (i == -1 && errno == EINTR && !(fb->flags & B_EOUT));
if (i == 0) {
errno = EAGAIN;
return -1; /* return of 0 means non-blocking */
***************
*** 908,915 ****
if (fb->flags & B_WR) rc1 = bflush(fb);
else rc1 = 0;
! rc2 = close(fb->fd);
! if (fb->fd_in != fb->fd) rc3 = close(fb->fd_in);
else rc3 = 0;
fb->inptr = fb->inbase;
--- 1068,1075 ----
if (fb->flags & B_WR) rc1 = bflush(fb);
else rc1 = 0;
! rc2 = closesocket(fb->fd);
! if (fb->fd_in != fb->fd) rc3 = closesocket(fb->fd_in);
else rc3 = 0;
fb->inptr = fb->inbase;
1.13 +2 -1 apache/src/buff.h
Index: buff.h
===================================================================
RCS file: /export/home/cvs/apache/src/buff.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -C3 -r1.12 -r1.13
*** buff.h 1997/02/10 15:49:54 1.12
--- buff.h 1997/06/15 19:22:24 1.13
***************
*** 94,106 ****
/* could also put pointers to the basic I/O routines here */
int fd; /* the file descriptor */
int fd_in; /* input file descriptor, if different */
};
/* Options to bset/getopt */
#define BO_BYTECT (1)
/* Stream creation and modification */
! extern BUFF *bcreate(pool *p, int flags);
extern void bpushfd(BUFF *fb, int fd_in, int fd_out);
extern int bsetopt(BUFF *fb, int optname, const void *optval);
extern int bgetopt(BUFF *fb, int optname, void *optval);
--- 94,107 ----
/* could also put pointers to the basic I/O routines here */
int fd; /* the file descriptor */
int fd_in; /* input file descriptor, if different */
+ int is_socket; /* whether fd/fd_in are sockets */
};
/* Options to bset/getopt */
#define BO_BYTECT (1)
/* Stream creation and modification */
! extern BUFF *bcreate(pool *p, int flags, int is_socket);
extern void bpushfd(BUFF *fb, int fd_in, int fd_out);
extern int bsetopt(BUFF *fb, int optname, const void *optval);
extern int bgetopt(BUFF *fb, int optname, void *optval);
1.100 +74 -13 apache/src/conf.h
Index: conf.h
===================================================================
RCS file: /export/home/cvs/apache/src/conf.h,v
retrieving revision 1.99
retrieving revision 1.100
diff -C3 -r1.99 -r1.100
*** conf.h 1997/06/04 07:03:11 1.99
--- conf.h 1997/06/15 19:22:24 1.100
***************
*** 55,61 ****
* See README for a listing of what they mean
*/
! #if !defined(QNX) && !defined(MPE)
#include <sys/param.h>
#endif
--- 55,61 ----
* See README for a listing of what they mean
*/
! #if !defined(QNX) && !defined(MPE) && !defined(WIN32)
#include <sys/param.h>
#endif
***************
*** 500,505 ****
--- 500,551 ----
#define JMP_BUF sigjmp_buf
#define USE_FCNTL_SERIALIZED_ACCEPT
+ #elif defined(WIN32)
+ /* Put your NT stuff here - Ambarish */
+
+ /* temporarily replace crypt */
+ //char *crypt(const char *pw, const char *salt);
+ #define crypt(buf,salt) (buf)
+
+ /* Although DIR_TYPE is dirent (see nt/readdir.h) we need direct.h for
+ chdir() */
+ #include <direct.h>
+
+ #define WIN32_LEAN_AND_MEAN
+ #define STRICT
+ #define NO_UNISTD_H
+ #define NO_WRITEV
+ #define NO_SETSID
+ #define NO_USE_SIGACTION
+ #define NEED_PROCESS_H
+ #define USE_LONGJMP
+ #define HAVE_MMAP
+ #define MULTITHREAD
+ typedef int uid_t;
+ typedef int gid_t;
+ typedef int pid_t;
+ typedef int mode_t;
+ typedef char * caddr_t;
+ #define strcasecmp(s1, s2) stricmp(s1, s2)
+ #define strncasecmp(s1, s2, n) strnicmp(s1, s2, n)
+ #define lstat(x, y) stat(x, y)
+ #define S_ISLNK(m) (0)
+ #define S_ISREG(m) ((m & _S_IFREG) == _S_IFREG)
+ #ifndef S_ISDIR
+ #define S_ISDIR(m) (((m) & S_IFDIR) == S_IFDIR)
+ #endif
+ #ifndef S_ISREG
+ #define S_ISREG(m) (((m)&(S_IFREG)) == (S_IFREG))
+ #endif
+ #define STDIN_FILENO 0
+ #define STDOUT_FILENO 1
+ #define STDERR_FILENO 2
+ #define JMP_BUF jmp_buf
+ #define sleep(t) Sleep(t*1000)
+ #define O_CREAT _O_CREAT
+ #define O_RDWR _O_RDWR
+ #define SIGPIPE 17
+ #include <stddef.h>
/* Unknown system - Edit these to match */
#else
#ifdef BSD
***************
*** 545,587 ****
int ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap);
#endif
! #if !defined(NEXT) && !defined(CONVEXOS)
#include <dirent.h>
#define DIR_TYPE dirent
! #else
#include <sys/dir.h>
#define DIR_TYPE direct
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
! #ifndef MPE
#include <sys/file.h>
#endif
#include <sys/socket.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
! #endif
! #include <ctype.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#ifndef MPE
#include <arpa/inet.h> /* for inet_ntoa */
! #endif
! #include <time.h> /* for ctime */
! #include <signal.h>
! #include <errno.h>
#include <sys/wait.h>
#include <pwd.h>
#include <grp.h>
#include <fcntl.h>
#include <limits.h>
#if !defined(QNX) && !defined(CONVEXOS11) && !defined(NEXT)
#include <memory.h>
#endif
#ifdef NEED_PROCESS_H
#include <process.h>
#endif
--- 591,648 ----
int ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap);
#endif
! #if !defined(NEXT) && !defined(CONVEXOS) && !defined(WIN32)
#include <dirent.h>
#define DIR_TYPE dirent
! #elif !defined(WIN32)
#include <sys/dir.h>
#define DIR_TYPE direct
+ #else
+ #define DIR_TYPE dirent
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
! #include <ctype.h>
! #if !defined(MPE) && !defined(WIN32)
#include <sys/file.h>
#endif
+ #ifndef WIN32
#include <sys/socket.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
! #endif /* HAVE_SYS_SELECT_H */
#include <netinet/in.h>
#include <netdb.h>
#include <sys/ioctl.h>
#ifndef MPE
#include <arpa/inet.h> /* for inet_ntoa */
! #endif /* ndef MPE */
#include <sys/wait.h>
#include <pwd.h>
#include <grp.h>
#include <fcntl.h>
#include <limits.h>
+ #define closesocket(s) close(s)
+ #define O_BINARY (0)
+
+ #else /* WIN32 */
+ #include <winsock.h>
+ #include <malloc.h>
+ #include <io.h>
+ #include <fcntl.h>
+ #endif /* ndef WIN32 */
+
+ #include <time.h> /* for ctime */
+ #include <signal.h>
+ #include <errno.h>
#if !defined(QNX) && !defined(CONVEXOS11) && !defined(NEXT)
#include <memory.h>
#endif
+
+
#ifdef NEED_PROCESS_H
#include <process.h>
#endif
***************
*** 596,602 ****
#endif
#endif
#ifdef HAVE_MMAP
! #ifndef __EMX__
/* This file is not needed for OS/2 */
#include <sys/mman.h>
#endif
--- 657,663 ----
#endif
#endif
#ifdef HAVE_MMAP
! #if !defined(__EMX__) && !defined(WIN32)
/* This file is not needed for OS/2 */
#include <sys/mman.h>
#endif
***************
*** 613,619 ****
#define LOGNAME_MAX 25
#endif
! #ifndef NEXT
#include <unistd.h>
#endif
--- 674,680 ----
#define LOGNAME_MAX 25
#endif
! #if !defined(NEXT) && !defined(WIN32)
#include <unistd.h>
#endif
***************
*** 749,752 ****
long vfprintf (FILE *, char *, va_list);
! #endif
--- 810,813 ----
long vfprintf (FILE *, char *, va_list);
! #endif /* SUNOS_LIB_PROTOTYPES */
1.10 +2 -0 apache/src/http_conf_globals.h
Index: http_conf_globals.h
===================================================================
RCS file: /export/home/cvs/apache/src/http_conf_globals.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -C3 -r1.9 -r1.10
*** http_conf_globals.h 1997/01/01 18:10:16 1.9
--- http_conf_globals.h 1997/06/15 19:22:25 1.10
***************
*** 62,67 ****
--- 62,69 ----
extern gid_t group_id_list[NGROUPS_MAX];
#endif
extern int max_requests_per_child;
+ extern int threads_per_child;
+ extern int excess_requests_per_child;
extern struct in_addr bind_address;
extern listen_rec *listeners;
extern int daemons_to_start;
1.83 +15 -2 apache/src/http_core.c
Index: http_core.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.c,v
retrieving revision 1.82
retrieving revision 1.83
diff -C3 -r1.82 -r1.83
*** http_core.c 1997/06/10 00:28:31 1.82
--- http_core.c 1997/06/15 19:22:25 1.83
***************
*** 1020,1025 ****
--- 1020,1036 ----
return NULL;
}
+ const char *set_threads (cmd_parms *cmd, void *dummy, char *arg) {
+ threads_per_child = atoi (arg);
+ return NULL;
+ }
+
+ const char *set_excess_requests (cmd_parms *cmd, void *dummy, char *arg) {
+ excess_requests_per_child = atoi (arg);
+ return NULL;
+ }
+
+
#if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC)
static void set_rlimit(cmd_parms *cmd, struct rlimit **plimit, const char *arg,
const char * arg2, int type)
***************
*** 1258,1263 ****
--- 1269,1276 ----
{ "AddModule", add_module_command, NULL, RSRC_CONF, ITERATE,
"the name of a module" },
{ "ClearModuleList", clear_module_list_command, NULL, RSRC_CONF, NO_ARGS, NULL },
+ { "ThreadsPerChild", set_threads, NULL, RSRC_CONF, TAKE1, "Number of threads a child creates" },
+ { "ExcessRequestsPerChild", set_excess_requests, NULL, RSRC_CONF, TAKE1, "Maximum number of requests a particular child serves after it is ready to die." },
{ NULL },
};
***************
*** 1325,1332 ****
return NOT_FOUND;
}
if (r->method_number != M_GET) return METHOD_NOT_ALLOWED;
!
! #ifdef __EMX__
/* Need binary mode for OS/2 */
f = pfopen (r->pool, r->filename, "rb");
#else
--- 1338,1345 ----
return NOT_FOUND;
}
if (r->method_number != M_GET) return METHOD_NOT_ALLOWED;
!
! #if defined(__EMX__) || defined(WIN32)
/* Need binary mode for OS/2 */
f = pfopen (r->pool, r->filename, "rb");
#else
1.14 +12 -3 apache/src/http_log.c
Index: http_log.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_log.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -C3 -r1.13 -r1.14
*** http_log.c 1997/03/22 23:51:01 1.13
--- http_log.c 1997/06/15 19:22:25 1.14
***************
*** 65,86 ****
#include <stdarg.h>
! void error_log_child (void *cmd)
{
/* Child process code for 'ErrorLog "|..."';
* may want a common framework for this, since I expect it will
* be common for other foo-loggers to want this sort of thing...
*/
!
cleanup_for_exec();
signal (SIGHUP, SIG_IGN);
! #ifdef __EMX__
/* For OS/2 we need to use a '/' */
execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
exit (1);
}
void open_error_log(server_rec *s, pool *p)
--- 65,95 ----
#include <stdarg.h>
! static int
! error_log_child (void *cmd)
{
/* Child process code for 'ErrorLog "|..."';
* may want a common framework for this, since I expect it will
* be common for other foo-loggers to want this sort of thing...
*/
! int child_pid = 0;
!
cleanup_for_exec();
+ #ifdef SIGHUP
+ /* No concept of a child process on Win32 */
signal (SIGHUP, SIG_IGN);
! #endif /* ndef SIGHUP */
! #if defined(WIN32)
! child_pid = spawnl (_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
! return(child_pid);
! #elif defined(__EMX__)
/* For OS/2 we need to use a '/' */
execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
exit (1);
+ return(child_pid);
}
void open_error_log(server_rec *s, pool *p)
1.150 +1232 -187 apache/src/http_main.c
Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.c,v
retrieving revision 1.149
retrieving revision 1.150
diff -C3 -r1.149 -r1.150
*** http_main.c 1997/05/29 04:50:27 1.149
--- http_main.c 1997/06/15 19:22:26 1.150
***************
*** 84,89 ****
--- 84,90 ----
#include "http_conf_globals.h"
#include "http_core.h" /* for get_remote_host */
#include "scoreboard.h"
+ #include "multithread.h"
#include <assert.h>
#include <sys/stat.h>
#ifdef HAVE_SHMGET
***************
*** 96,102 ****
--- 97,107 ----
#include <sys/audit.h>
#include <prot.h>
#endif
+ #ifdef WIN32
+ #include "nt/getopt.h"
+ #else
#include <netinet/tcp.h>
+ #endif
#ifdef HAVE_BSTRING_H
#include <bstring.h> /* for IRIX, FD_SET calls bzero() */
***************
*** 108,113 ****
--- 113,123 ----
#define max(a,b) (a > b ? a : b)
#endif
+ #ifdef WIN32
+ #include "nt/service.h"
+ #endif
+
+
#ifdef __EMX__
/* Add MMAP style functionality to OS/2 */
#ifdef HAVE_MMAP
***************
*** 136,141 ****
--- 146,153 ----
gid_t group_id_list[NGROUPS_MAX];
#endif
int max_requests_per_child;
+ int threads_per_child;
+ int excess_requests_per_child;
char *pid_fname;
char *scoreboard_fname;
char *server_argv0;
***************
*** 154,160 ****
/* *Non*-shared http_main globals... */
server_rec *server_conf;
! JMP_BUF jmpbuffer;
int sd;
static fd_set listenfds;
static int listenmaxfd;
--- 166,172 ----
/* *Non*-shared http_main globals... */
server_rec *server_conf;
! JMP_BUF __declspec( thread ) jmpbuffer;
int sd;
static fd_set listenfds;
static int listenmaxfd;
***************
*** 175,185 ****
--- 187,201 ----
/* small utility macros to make things easier to read */
+ #ifdef WIN32
+ #define ap_killpg(x, y)
+ #else
#ifdef NO_KILLPG
#define ap_killpg(x, y) (kill (-(x), (y)))
#else
#define ap_killpg(x, y) (killpg ((x), (y)))
#endif
+ #endif /* WIN32 */
#if defined(USE_FCNTL_SERIALIZED_ACCEPT)
static struct flock lock_it;
***************
*** 335,345 ****
* one timeout in progress at a time...
*/
! static conn_rec *current_conn;
! static request_rec *timeout_req;
! static char *timeout_name = NULL;
! static int alarms_blocked = 0;
! static int alarm_pending = 0;
#ifndef NO_USE_SIGACTION
/*
--- 351,361 ----
* one timeout in progress at a time...
*/
! static __declspec( thread ) conn_rec * current_conn;
! static __declspec( thread ) request_rec *timeout_req;
! static __declspec( thread ) char *timeout_name = NULL;
! static __declspec( thread ) int alarms_blocked = 0;
! static __declspec( thread ) int alarm_pending = 0;
#ifndef NO_USE_SIGACTION
/*
***************
*** 440,455 ****
}
}
void keepalive_timeout (char *name, request_rec *r)
{
timeout_req = r;
timeout_name = name;
!
! signal(SIGALRM, timeout);
if (r->connection->keptalive)
! alarm (r->server->keep_alive_timeout);
else
! alarm (r->server->timeout);
}
void hard_timeout (char *name, request_rec *r)
--- 456,555 ----
}
}
+
+ static __declspec( thread ) void (*alarm_fn)(int) = NULL;
+ #ifdef WIN32
+ static __declspec( thread ) unsigned int alarm_expiry_time = 0;
+ #endif /* WIN32 */
+
+ unsigned int
+ set_callback_and_alarm(void (*fn)(int), int x)
+ {
+ unsigned int old;
+
+ #ifdef WIN32
+ old = alarm_expiry_time;
+ if(old)
+ old -= time(0);
+ if(x == 0)
+ {
+ alarm_fn = NULL;
+ alarm_expiry_time = 0;
+ }
+ else
+ {
+ alarm_fn = fn;
+ alarm_expiry_time = time(NULL) + x;
+ }
+ #else
+ if(x)
+ alarm_fn = fn;
+ signal(SIGALRM, fn);
+ old = alarm(x);
+ #endif
+ return(old);
+ }
+
+
+ int
+ check_alarm()
+ {
+ #ifdef WIN32
+ if(alarm_expiry_time)
+ {
+ unsigned int t;
+
+ t = time(NULL);
+ if(t >= alarm_expiry_time)
+ {
+ alarm_expiry_time = 0;
+ (*alarm_fn)(0);
+ return(-1);
+ }
+ else
+ {
+ return(alarm_expiry_time - t);
+ }
+ }
+ else
+ return(0);
+ #else
+ return(0);
+ #endif /* WIN32 */
+ }
+
+
+
+ /* reset_timeout (request_rec *) resets the timeout in effect,
+ * as long as it hasn't expired already.
+ */
+
+ void reset_timeout (request_rec *r) {
+ int i;
+
+ if (timeout_name) { /* timeout has been set */
+ i = set_callback_and_alarm(alarm_fn, r->server->timeout);
+ if (i == 0) /* timeout already expired, so set it back to 0 */
+ set_callback_and_alarm(alarm_fn, 0);
+ }
+ }
+
+
+
+
void keepalive_timeout (char *name, request_rec *r)
{
+ unsigned int to;
+
timeout_req = r;
timeout_name = name;
!
if (r->connection->keptalive)
! to = r->server->keep_alive_timeout;
else
! to = r->server->timeout;
! set_callback_and_alarm(timeout, to);
!
}
void hard_timeout (char *name, request_rec *r)
***************
*** 457,493 ****
timeout_req = r;
timeout_name = name;
! signal(SIGALRM, timeout);
! alarm (r->server->timeout);
}
void soft_timeout (char *name, request_rec *r)
{
timeout_name = name;
! signal(SIGALRM, timeout);
! alarm (r->server->timeout);
}
void kill_timeout (request_rec *dummy) {
! alarm (0);
timeout_req = NULL;
timeout_name = NULL;
}
- /* reset_timeout (request_rec *) resets the timeout in effect,
- * as long as it hasn't expired already.
- */
-
- void reset_timeout (request_rec *r) {
- int i;
-
- if (timeout_name) { /* timeout has been set */
- i = alarm(r->server->timeout);
- if (i == 0) /* timeout already expired, so set it back to 0 */
- alarm(0);
- }
- }
/*
* More machine-dependent networking gooo... on some systems,
--- 557,580 ----
timeout_req = r;
timeout_name = name;
! set_callback_and_alarm(timeout, r->server->timeout);
!
}
void soft_timeout (char *name, request_rec *r)
{
timeout_name = name;
! set_callback_and_alarm(timeout, r->server->timeout);
!
}
void kill_timeout (request_rec *dummy) {
! set_callback_and_alarm(NULL, 0);
timeout_req = NULL;
timeout_name = NULL;
}
/*
* More machine-dependent networking gooo... on some systems,
***************
*** 538,545 ****
/* Special version of timeout for lingering_close */
! static void lingerout(sig)
! int sig;
{
if (alarms_blocked) {
alarm_pending = 1;
--- 625,631 ----
/* Special version of timeout for lingering_close */
! static void lingerout(int sig)
{
if (alarms_blocked) {
alarm_pending = 1;
***************
*** 557,564 ****
{
timeout_name = "lingering close";
! signal(SIGALRM, lingerout);
! alarm(MAX_SECS_TO_LINGER);
}
/* Since many clients will abort a connection instead of closing it,
--- 643,649 ----
{
timeout_name = "lingering close";
! set_callback_and_alarm(lingerout, MAX_SECS_TO_LINGER);
}
/* Since many clients will abort a connection instead of closing it,
***************
*** 653,658 ****
--- 738,772 ----
* We begin with routines which deal with the file itself...
*/
+ #ifdef MULTITHREAD
+ /*
+ * In the multithreaded mode, have multiple threads - not multiple
+ * processes that need to talk to each other. Just use a simple
+ * malloc. But let the routines that follow, think that you have
+ * shared memory (so they use memcpy etc.)
+ */
+ #undef HAVE_MMAP
+ #define HAVE_MMAP 1
+ static scoreboard *scoreboard_image = NULL;
+
+ void reinit_scoreboard (pool *p)
+ {
+ assert(!scoreboard_image);
+ scoreboard_image = (scoreboard *)calloc(HARD_SERVER_LIMIT, sizeof(short_score));
+ }
+
+ void cleanup_scoreboard ()
+ {
+ assert(scoreboard_image);
+ free(scoreboard_image);
+ scoreboard_image = NULL;
+ }
+
+ void sync_scoreboard_image ()
+ {}
+
+
+ #else /* MULTITHREAD */
#if defined(HAVE_MMAP)
static scoreboard *scoreboard_image=NULL;
***************
*** 941,946 ****
--- 1055,1062 ----
#endif
}
+ #endif /* MULTITHREAD */
+
int update_child_status (int child_num, int status, request_rec *r)
{
int old_status;
***************
*** 1110,1115 ****
--- 1226,1232 ----
void reclaim_child_processes ()
{
+ #ifndef MULTITHREAD
int i, status;
int my_pid = getpid();
***************
*** 1169,1174 ****
--- 1286,1292 ----
}
}
}
+ #endif /* ndef MULTITHREAD */
}
#if defined(BROKEN_WAIT) || defined(NEED_WAITPID)
***************
*** 1203,1208 ****
--- 1321,1360 ----
static int wait_or_timeout ()
{
+ #ifdef WIN32
+ #define MAXWAITOBJ MAXIMUM_WAIT_OBJECTS
+ HANDLE h[MAXWAITOBJ];
+ int e[MAXWAITOBJ];
+ int round, pi, hi, rv, err;
+ for(round=0; round<=(HARD_SERVER_LIMIT-1)/MAXWAITOBJ+1; round++)
+ {
+ hi = 0;
+ for(pi=round*MAXWAITOBJ;
+ (pi<(round+1)*MAXWAITOBJ) && (pi<HARD_SERVER_LIMIT);
+ pi++)
+ {
+ if(scoreboard_image->servers[pi].status != SERVER_DEAD)
+ {
+ e[hi] = pi;
+ h[hi++] = (HANDLE)scoreboard_image->servers[pi].pid;
+ }
+
+ }
+ if(hi > 0)
+ {
+ rv = WaitForMultipleObjects(hi, h, FALSE, 10000);
+ if(rv == -1)
+ err = GetLastError();
+ if((WAIT_OBJECT_0 <= (unsigned int)rv) && ((unsigned int)rv < (WAIT_OBJECT_0 + hi)))
+ return(scoreboard_image->servers[e[rv - WAIT_OBJECT_0]].pid);
+ else if((WAIT_ABANDONED_0 <= (unsigned int)rv) && ((unsigned int)rv < (WAIT_ABANDONED_0 + hi)))
+ return(scoreboard_image->servers[e[rv - WAIT_ABANDONED_0]].pid);
+
+ }
+ }
+ return(-1);
+
+ #else /* WIN32 */
#ifndef NEED_WAITPID
int ret;
***************
*** 1221,1233 ****
--- 1373,1388 ----
}
return -1;
#endif
+ #endif /* WIN32 */
}
void sig_term() {
log_error("httpd: caught SIGTERM, shutting down", server_conf);
cleanup_scoreboard();
+ #ifdef SIGKILL
ap_killpg (pgrp, SIGKILL);
+ #endif /* SIGKILL */
close(sd);
exit(1);
}
***************
*** 1283,1289 ****
--- 1438,1448 ----
static void restart (int sig)
{
+ #ifdef WIN32
+ is_graceful = 0;
+ #else
is_graceful = (sig == SIGUSR1);
+ #endif /* WIN32 */
restart_pending = 1;
}
***************
*** 1327,1339 ****
log_unixerr ("sigaction(SIGUSR1)", NULL, NULL, server_conf);
#else
if(!one_process) {
! signal (SIGSEGV, (void (*)())seg_fault);
! signal (SIGBUS, (void (*)())bus_error);
}
! signal (SIGTERM, (void (*)())sig_term);
! signal (SIGHUP, (void (*)())restart);
signal (SIGUSR1, (void (*)())restart);
#endif
}
--- 1486,1504 ----
log_unixerr ("sigaction(SIGUSR1)", NULL, NULL, server_conf);
#else
if(!one_process) {
! signal (SIGSEGV, (void (*)(int))seg_fault);
! #ifdef SIGBUS
! signal (SIGBUS, (void (*)(int))bus_error);
! #endif /* SIGBUS */
}
! signal (SIGTERM, (void (*)(int))sig_term);
! #ifdef SIGHUP
! signal (SIGHUP, (void (*)(int))restart);
! #endif /* SIGHUP */
! #ifdef SIGUSR1
signal (SIGUSR1, (void (*)())restart);
+ #endif /* SIGUSR1 */
#endif
}
***************
*** 1344,1349 ****
--- 1509,1515 ----
void detach()
{
+ #ifndef WIN32
int x;
chdir("/");
***************
*** 1371,1378 ****
exit(1);
}
#elif defined(__EMX__)
! /* OS/2 doesn't support process group IDs */
! pgrp=getpid();
#elif defined(MPE)
/* MPE uses negative pid for process group */
pgrp=-getpid();
--- 1537,1544 ----
exit(1);
}
#elif defined(__EMX__)
! /* OS/2 don't support process group IDs */
! pgrp=-getpid();
#elif defined(MPE)
/* MPE uses negative pid for process group */
pgrp=-getpid();
***************
*** 1382,1388 ****
fprintf(stderr,"httpd: setpgrp failed\n");
exit(1);
}
! #endif
}
/* Reset group privileges, after rereading the config files
--- 1548,1555 ----
fprintf(stderr,"httpd: setpgrp failed\n");
exit(1);
}
! #endif
! #endif /* ndef WIN32 */
}
/* Reset group privileges, after rereading the config files
***************
*** 1399,1404 ****
--- 1566,1572 ----
static void set_group_privs()
{
+ #ifndef WIN32
if(!geteuid()) {
char *name;
***************
*** 1437,1447 ****
--- 1605,1617 ----
}
#endif
}
+ #endif /* ndef WIN32 */
}
/* check to see if we have the 'suexec' setuid wrapper installed */
int init_suexec ()
{
+ #ifndef WIN32
struct stat wrapper;
if ((stat(SUEXEC_BIN, &wrapper)) != 0)
***************
*** 1451,1457 ****
suexec_enabled = 1;
fprintf(stderr, "Configuring Apache for use with suexec wrapper.\n");
}
!
return (suexec_enabled);
}
--- 1621,1627 ----
suexec_enabled = 1;
fprintf(stderr, "Configuring Apache for use with suexec wrapper.\n");
}
! #endif /* ndef WIN32 */
return (suexec_enabled);
}
***************
*** 1637,1642 ****
--- 1807,2001 ----
#define sock_disable_nagle(s) /* NOOP */
#endif
+ static int make_sock(pool *pconf, const struct sockaddr_in *server)
+ {
+ int s;
+ int one = 1;
+
+ if ((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) {
+ log_unixerr("socket", NULL, "Failed to get a socket, exiting child",
+ server_conf);
+ exit(1);
+ }
+
+ note_cleanups_for_socket(pconf, s); /* arrange to close on exec or restart */
+
+ #ifndef MPE
+ /* MPE does not support SO_REUSEADDR and SO_KEEPALIVE */
+ if (setsockopt(s, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(int)) < 0) {
+ log_unixerr("setsockopt", "(SO_REUSEADDR)", NULL, server_conf);
+ exit(1);
+ }
+ one = 1;
+ if (setsockopt(s, SOL_SOCKET,SO_KEEPALIVE,(char *)&one,sizeof(int)) < 0) {
+ log_unixerr("setsockopt", "(SO_KEEPALIVE)", NULL, server_conf);
+ exit(1);
+ }
+ #endif
+
+ sock_disable_nagle(s);
+ sock_enable_linger(s);
+
+ /*
+ * To send data over high bandwidth-delay connections at full
+ * speed we must force the TCP window to open wide enough to keep the
+ * pipe full. The default window size on many systems
+ * is only 4kB. Cross-country WAN connections of 100ms
+ * at 1Mb/s are not impossible for well connected sites.
+ * If we assume 100ms cross-country latency,
+ * a 4kB buffer limits throughput to 40kB/s.
+ *
+ * To avoid this problem I've added the SendBufferSize directive
+ * to allow the web master to configure send buffer size.
+ *
+ * The trade-off of larger buffers is that more kernel memory
+ * is consumed. YMMV, know your customers and your network!
+ *
+ * -John Heidemann <jo...@isi.edu> 25-Oct-96
+ *
+ * If no size is specified, use the kernel default.
+ */
+ if (server_conf->send_buffer_size) {
+ if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
+ (char *)&server_conf->send_buffer_size, sizeof(int)) < 0) {
+ log_unixerr("setsockopt", "(SO_SNDBUF)",
+ "Failed to set SendBufferSize, using default",
+ server_conf);
+ /* not a fatal error */
+ }
+ }
+
+ #ifdef MPE
+ /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
+ if (ntohs(server->sin_port) < 1024) GETPRIVMODE();
+ #endif
+ if(bind(s, (struct sockaddr *)server,sizeof(struct sockaddr_in)) == -1)
+ {
+ perror("bind");
+ #ifdef MPE
+ if (ntohs(server->sin_port) < 1024) GETUSERMODE();
+ #endif
+ if (server->sin_addr.s_addr != htonl(INADDR_ANY))
+ fprintf(stderr,"httpd: could not bind to address %s port %d\n",
+ inet_ntoa(server->sin_addr), ntohs(server->sin_port));
+ else
+ fprintf(stderr,"httpd: could not bind to port %d\n",
+ ntohs(server->sin_port));
+ exit(1);
+ }
+ #ifdef MPE
+ if (ntohs(server->sin_port) < 1024) GETUSERMODE();
+ #endif
+ listen(s, 512);
+ return s;
+ }
+
+ static listen_rec *old_listeners;
+
+ static void copy_listeners(pool *p)
+ {
+ listen_rec *lr;
+
+ assert(old_listeners == NULL);
+ for(lr=listeners ; lr ; lr=lr->next)
+ {
+ listen_rec *nr=malloc(sizeof *nr);
+ if (nr == NULL) {
+ fprintf (stderr, "Ouch! malloc failed in copy_listeners()\n");
+ exit (1);
+ }
+ *nr=*lr;
+ kill_cleanups_for_socket(p,nr->fd);
+ nr->next=old_listeners;
+ assert(!nr->used);
+ old_listeners=nr;
+ }
+ }
+
+ static int find_listener(listen_rec *lr)
+ {
+ listen_rec *or;
+
+ for(or=old_listeners ; or ; or=or->next)
+ if(!memcmp(&or->local_addr,&lr->local_addr,sizeof or->local_addr))
+ {
+ or->used=1;
+ return or->fd;
+ }
+ return -1;
+ }
+
+ static void close_unused_listeners()
+ {
+ listen_rec *or,*next;
+
+ for(or=old_listeners ; or ; or=next)
+ {
+ next=or->next;
+ if(!or->used)
+ closesocket(or->fd);
+ free(or);
+ }
+ old_listeners=NULL;
+ }
+
+
+ static int s_iInitCount = 0;
+
+ int
+ AMCSocketInitialize()
+ {
+ #ifdef WIN32
+ int iVersionRequested;
+ WSADATA wsaData;
+ int err;
+
+ if(s_iInitCount > 0)
+ {
+ s_iInitCount++;
+ return(0);
+ }
+ else if(s_iInitCount < 0)
+ return(s_iInitCount);
+
+ /* s_iInitCount == 0. Do the initailization */
+ iVersionRequested = MAKEWORD(1, 1);
+ err = WSAStartup((WORD)iVersionRequested, &wsaData);
+ if(err)
+ {
+ s_iInitCount = -1;
+ return(s_iInitCount);
+ }
+ if ( LOBYTE( wsaData.wVersion ) != 1 ||
+ HIBYTE( wsaData.wVersion ) != 1 )
+ {
+ s_iInitCount = -2;
+ WSACleanup();
+ return(s_iInitCount);
+ }
+ #else
+ signal(SIGPIPE, SIG_IGN);
+ #endif /* WIN32 */
+
+ s_iInitCount++;
+ return(s_iInitCount);
+
+ }
+
+
+ void
+ AMCSocketCleanup()
+ {
+ #ifdef WIN32
+ if(--s_iInitCount == 0)
+ WSACleanup();
+ #else /* not WIN32 */
+ s_iInitCount--;
+ #endif /* WIN32 */
+ return;
+ }
+
+ #ifndef MULTITHREAD
/*****************************************************************
* Child process main loop.
* The following vars are static to avoid getting clobbered by longjmp();
***************
*** 1831,1837 ****
(void)update_child_status(child_num, SERVER_BUSY_READ,
(request_rec*)NULL);
! conn_io = bcreate(ptrans, B_RDWR);
dupped_csd = csd;
#if defined(NEED_DUPPED_CSD)
if ((dupped_csd = dup(csd)) < 0) {
--- 2190,2196 ----
(void)update_child_status(child_num, SERVER_BUSY_READ,
(request_rec*)NULL);
! conn_io = bcreate(ptrans, B_RDWR, 1);
dupped_csd = csd;
#if defined(NEED_DUPPED_CSD)
if ((dupped_csd = dup(csd)) < 0) {
***************
*** 1970,2110 ****
return 0;
}
- static int make_sock(pool *pconf, const struct sockaddr_in *server)
- {
- int s;
- int one = 1;
! if ((s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1) {
! log_unixerr("socket", NULL, "Failed to get a socket, exiting child",
! server_conf);
! exit(1);
! }
!
! note_cleanups_for_fd(pconf, s); /* arrange to close on exec or restart */
!
! #ifndef MPE
! /* MPE does not support SO_REUSEADDR and SO_KEEPALIVE */
! if (setsockopt(s, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(int)) < 0) {
! log_unixerr("setsockopt", "(SO_REUSEADDR)", NULL, server_conf);
! exit(1);
! }
! one = 1;
! if (setsockopt(s, SOL_SOCKET,SO_KEEPALIVE,(char *)&one,sizeof(int)) < 0) {
! log_unixerr("setsockopt", "(SO_KEEPALIVE)", NULL, server_conf);
! exit(1);
! }
! #endif
!
! sock_disable_nagle(s);
! sock_enable_linger(s);
!
! /*
! * To send data over high bandwidth-delay connections at full
! * speed we must force the TCP window to open wide enough to keep the
! * pipe full. The default window size on many systems
! * is only 4kB. Cross-country WAN connections of 100ms
! * at 1Mb/s are not impossible for well connected sites.
! * If we assume 100ms cross-country latency,
! * a 4kB buffer limits throughput to 40kB/s.
! *
! * To avoid this problem I've added the SendBufferSize directive
! * to allow the web master to configure send buffer size.
! *
! * The trade-off of larger buffers is that more kernel memory
! * is consumed. YMMV, know your customers and your network!
! *
! * -John Heidemann <jo...@isi.edu> 25-Oct-96
! *
! * If no size is specified, use the kernel default.
! */
! if (server_conf->send_buffer_size) {
! if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
! (char *)&server_conf->send_buffer_size, sizeof(int)) < 0) {
! log_unixerr("setsockopt", "(SO_SNDBUF)",
! "Failed to set SendBufferSize, using default",
! server_conf);
! /* not a fatal error */
! }
! }
!
! #ifdef MPE
! /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
! if (ntohs(server->sin_port) < 1024) GETPRIVMODE();
! #endif
! if(bind(s, (struct sockaddr *)server,sizeof(struct sockaddr_in)) == -1)
! {
! perror("bind");
! #ifdef MPE
! if (ntohs(server->sin_port) < 1024) GETUSERMODE();
! #endif
! if (server->sin_addr.s_addr != htonl(INADDR_ANY))
! fprintf(stderr,"httpd: could not bind to address %s port %d\n",
! inet_ntoa(server->sin_addr), ntohs(server->sin_port));
! else
! fprintf(stderr,"httpd: could not bind to port %d\n",
! ntohs(server->sin_port));
! exit(1);
! }
! #ifdef MPE
! if (ntohs(server->sin_port) < 1024) GETUSERMODE();
! #endif
! listen(s, 512);
! return s;
! }
!
! static listen_rec *old_listeners;
!
! static void copy_listeners(pool *p)
! {
! listen_rec *lr;
!
! assert(old_listeners == NULL);
! for(lr=listeners ; lr ; lr=lr->next)
! {
! listen_rec *nr=malloc(sizeof *nr);
! if (nr == NULL) {
! fprintf (stderr, "Ouch! malloc failed in copy_listeners()\n");
! exit (1);
! }
! *nr=*lr;
! kill_cleanups_for_fd(p,nr->fd);
! nr->next=old_listeners;
! assert(!nr->used);
! old_listeners=nr;
! }
! }
!
! static int find_listener(listen_rec *lr)
! {
! listen_rec *or;
!
! for(or=old_listeners ; or ; or=or->next)
! if(!memcmp(&or->local_addr,&lr->local_addr,sizeof or->local_addr))
! {
! or->used=1;
! return or->fd;
! }
! return -1;
! }
!
! static void close_unused_listeners()
! {
! listen_rec *or,*next;
!
! for(or=old_listeners ; or ; or=next)
! {
! next=or->next;
! if(!or->used)
! close(or->fd);
! free(or);
! }
! old_listeners=NULL;
! }
!
! /*****************************************************************
! * Executive routines.
! */
void standalone_main(int argc, char **argv)
{
--- 2329,2338 ----
return 0;
}
! /*****************************************************************
! * Executive routines.
! */
void standalone_main(int argc, char **argv)
{
***************
*** 2439,2445 ****
exit(1);
}
server_conf->port =ntohs(((struct sockaddr_in *)&sa_server)->sin_port);
! cio = bcreate(ptrans, B_RDWR);
#ifdef MPE
/* HP MPE 5.5 inetd only passes the incoming socket as stdin (fd 0), whereas
HPUX inetd passes the incoming socket as stdin (fd 0) and stdout (fd 1).
--- 2667,2673 ----
exit(1);
}
server_conf->port =ntohs(((struct sockaddr_in *)&sa_server)->sin_port);
! cio = bcreate(ptrans, B_RDWR, 1);
#ifdef MPE
/* HP MPE 5.5 inetd only passes the incoming socket as stdin (fd 0), whereas
HPUX inetd passes the incoming socket as stdin (fd 0) and stdout (fd 1).
***************
*** 2515,2518 ****
--- 2743,3563 ----
}
#endif
#endif
+
+ #else /* ndef MULTITHREAD */
+
+
+
+
+ typedef struct joblist_s
+ {
+ struct joblist_s *next;
+ int sock;
+ } joblist;
+
+ typedef struct globals_s
+ {
+ int exit_now;
+ semaphore *jobsemaphore;
+ joblist *jobhead;
+ joblist *jobtail;
+ mutex *jobmutex;
+ int jobcount;
+ } globals;
+
+
+ globals allowed_globals = { 0, NULL, NULL, NULL, 0 };
+
+
+ void
+ add_job(int sock)
+ {
+ joblist *new_job;
+
+ assert(allowed_globals.jobmutex);
+ /* TODO: If too many jobs in queue, sleep, check for problems */
+ acquire_mutex(allowed_globals.jobmutex);
+ new_job = (joblist *)malloc(sizeof(joblist));
+ new_job->next = NULL;
+ new_job->sock = sock;
+ if(allowed_globals.jobtail != NULL)
+ allowed_globals.jobtail->next = new_job;
+ allowed_globals.jobtail = new_job;
+ if(!allowed_globals.jobhead)
+ allowed_globals.jobhead = new_job;
+ allowed_globals.jobcount++;
+ release_semaphore(allowed_globals.jobsemaphore);
+ release_mutex(allowed_globals.jobmutex);
+ }
+
+ int
+ remove_job()
+ {
+ joblist *job;
+ int sock;
+
+ assert(allowed_globals.jobmutex);
+ acquire_semaphore(allowed_globals.jobsemaphore);
+ acquire_mutex(allowed_globals.jobmutex);
+ if(allowed_globals.exit_now && !allowed_globals.jobhead)
+ {
+ release_mutex(allowed_globals.jobmutex);
+ return(-1);
+ }
+ job = allowed_globals.jobhead;
+ assert(job);
+ allowed_globals.jobhead = job->next;
+ if(allowed_globals.jobhead == NULL)
+ allowed_globals.jobtail = NULL;
+ release_mutex(allowed_globals.jobmutex);
+ sock = job->sock;
+ free(job);
+ return(sock);
+ }
+
+
+
+ void child_sub_main(int child_num, int srv,
+ int csd, int dupped_csd,
+ int requests_this_child, pool *pchild)
+ {
+ #if defined(UW)
+ size_t clen;
+ #else
+ int clen;
+ #endif
+ struct sockaddr sa_server;
+ struct sockaddr sa_client;
+
+ csd = -1;
+ dupped_csd = -1;
+ requests_this_child = 0;
+ (void)update_child_status(child_num, SERVER_READY, (request_rec*)NULL);
+
+ /*
+ * Setup the jump buffers so that we can return here after
+ * a signal or a timeout (yeah, I know, same thing).
+ */
+ #if defined(USE_LONGJMP)
+ setjmp(jmpbuffer);
+ #else
+ sigsetjmp(jmpbuffer,1);
+ #endif
+ #ifdef SIGURG
+ signal(SIGURG, timeout);
+ #endif
+
+
+ pchild = make_sub_pool(NULL);
+
+ while (1) {
+ BUFF *conn_io;
+ request_rec *r;
+
+ /*
+ * (Re)initialize this child to a pre-connection state.
+ */
+
+ set_callback_and_alarm(NULL, 0); /* Cancel any outstanding alarms. */
+ timeout_req = NULL; /* No request in progress */
+ current_conn = NULL;
+ #ifdef SIGPIPE
+ signal(SIGPIPE, timeout);
+ #endif
+
+ clear_pool (pchild);
+
+ (void)update_child_status(child_num, SERVER_READY, (request_rec*)NULL);
+
+ csd = remove_job();
+ if(csd == -1)
+ break; /* time to exit */
+ requests_this_child++;
+
+ note_cleanups_for_socket(pchild,csd);
+
+ /*
+ * We now have a connection, so set it up with the appropriate
+ * socket options, file descriptors, and read/write buffers.
+ */
+
+ clen = sizeof(sa_server);
+ if (getsockname(csd, &sa_server, &clen) < 0) {
+ log_unixerr("getsockname", NULL, NULL, server_conf);
+ continue;
+ }
+ clen = sizeof(sa_client);
+ if ((getpeername(csd, &sa_client, &clen)) < 0)
+ {
+ /* get peername will fail if the input isn't a socket */
+ perror("getpeername");
+ memset(&sa_client, '\0', sizeof(sa_client));
+ }
+
+ sock_disable_nagle(csd);
+
+ (void)update_child_status(child_num, SERVER_BUSY_READ,
+ (request_rec*)NULL);
+
+ conn_io = bcreate(pchild, B_RDWR, 1);
+ dupped_csd = csd;
+ #if defined(NEED_DUPPED_CSD)
+ if ((dupped_csd = dup(csd)) < 0) {
+ log_unixerr("dup", NULL, "couldn't duplicate csd", server_conf);
+ dupped_csd = csd; /* Oh well... */
+ }
+ note_cleanups_for_socket(pchild,dupped_csd);
+ #endif
+ bpushfd(conn_io, csd, dupped_csd);
+
+ current_conn = new_connection (pchild, server_conf, conn_io,
+ (struct sockaddr_in *)&sa_client,
+ (struct sockaddr_in *)&sa_server,
+ child_num);
+
+ /*
+ * Read and process each request found on our connection
+ * until no requests are left or we decide to close.
+ */
+
+ while ((r = read_request(current_conn)) != NULL) {
+ (void)update_child_status(child_num, SERVER_BUSY_WRITE, r);
+
+ process_request(r);
+ #if defined(STATUS)
+ increment_counts(child_num, r);
+ #endif
+ if (!current_conn->keepalive || current_conn->aborted)
+ break;
+
+ destroy_pool(r->pool);
+ (void)update_child_status(child_num, SERVER_BUSY_KEEPALIVE,
+ (request_rec*)NULL);
+
+ sync_scoreboard_image();
+ }
+
+ /*
+ * Close the connection, being careful to send out whatever is still
+ * in our buffers. If possible, try to avoid a hard close until the
+ * client has ACKed our FIN and/or has stopped sending us data.
+ */
+ kill_cleanups_for_socket(pchild,csd);
+
+ #ifdef NO_LINGCLOSE
+ bclose(conn_io); /* just close it */
+ #else
+ if (r && r->connection
+ && !r->connection->aborted
+ && r->connection->client
+ && (r->connection->client->fd >= 0)) {
+
+ lingering_close(r);
+ }
+ else {
+ bsetflag(conn_io, B_EOUT, 1);
+ bclose(conn_io);
+ }
+ #endif
+ }
+ destroy_pool(pchild);
+ (void)update_child_status(child_num,SERVER_DEAD, NULL);
+ }
+
+
+ void
+ child_main(int child_num_arg)
+ {
+
+ int srv = 0;
+ int csd = 0;
+ int dupped_csd = 0;
+ int requests_this_child = 0;
+ pool *ppool = NULL;
+
+ /*
+ * Only reason for this function, is to pass in
+ * arguments to child_sub_main() on its stack so
+ * that longjump doesn't try to corrupt its local
+ * variables and I don't need to make those
+ * damn variables static/global
+ */
+ child_sub_main(child_num_arg, srv,
+ csd, dupped_csd,
+ requests_this_child, ppool);
+
+ }
+
+
+
+ void
+ cleanup_thread(thread **handles, int *thread_cnt, int thread_to_clean)
+ {
+ int i;
+
+ free_thread(handles[thread_to_clean]);
+ for(i=thread_to_clean; i<((*thread_cnt)-1); i++)
+ handles[i] = handles[i+1];
+ (*thread_cnt)--;
+ }
+
+ /*****************************************************************
+ * Executive routines.
+ */
+
+ event *exit_event;
+ mutex *start_mutex;
+
+ void worker_main()
+ {
+ /*
+ * I am writing this stuff specifically for NT.
+ * have pulled out a lot of the restart and
+ * graceful restart stuff, because that is only
+ * useful on Unix (not sure it even makes sense
+ * in a multi-threaded env.
+ */
+ int saved_sd;
+ int nthreads;
+ fd_set main_fds;
+ int srv;
+ int clen;
+ int csd;
+ struct sockaddr_in sa_server;
+ struct sockaddr_in sa_client;
+ int total_jobs = 0;
+ thread **child_handles;
+ int rv;
+ time_t end_time;
+ int i;
+ struct timeval tv;
+ int wait_time = 100;
+ int start_exit = 0;
+ int count_down = 0;
+ int start_mutex_released = 0;
+ int max_jobs_per_exe;
+ int max_jobs_after_exit_request;
+
+ standalone = 1;
+ sd = listenmaxfd = -1;
+ nthreads = threads_per_child;
+ max_jobs_after_exit_request = excess_requests_per_child;
+ max_jobs_per_exe = max_requests_per_child;
+ if(nthreads <= 0)
+ nthreads = 40;
+ if(max_jobs_per_exe <= 0)
+ max_jobs_per_exe = 0;
+ if(max_jobs_after_exit_request <= 0)
+ max_jobs_after_exit_request = max_jobs_per_exe/10;
+
+ if (!one_process) detach();
+
+ ++generation;
+
+ copy_listeners(pconf);
+ saved_sd=sd;
+ restart_time = time(NULL);
+
+ reinit_scoreboard(pconf);
+ default_server_hostnames (server_conf);
+
+ acquire_mutex(start_mutex);
+ {
+ listenmaxfd = -1;
+ FD_ZERO(&listenfds);
+
+ if (listeners == NULL) {
+ memset((char *) &sa_server, 0, sizeof(sa_server));
+ sa_server.sin_family=AF_INET;
+ sa_server.sin_addr=bind_address;
+ sa_server.sin_port=htons(server_conf->port);
+
+ sd = make_sock(pconf, &sa_server);
+ FD_SET(sd, &listenfds);
+ listenmaxfd = sd;
+ }
+ else {
+ listen_rec *lr;
+ int fd;
+
+
+ for (lr=listeners; lr != NULL; lr=lr->next)
+ {
+ fd=find_listener(lr);
+ if(fd < 0)
+ {
+ fd = make_sock(pconf, &lr->local_addr);
+ }
+ FD_SET(fd, &listenfds);
+ if (fd > listenmaxfd) listenmaxfd = fd;
+ lr->fd=fd;
+ }
+ close_unused_listeners();
+ sd = -1;
+ }
+ }
+
+ set_signals();
+
+ /*
+ * - Initialize allowed_globals
+ * - Create the thread table
+ * - Spawn off threads
+ * - Create listen socket set (done above)
+ * - loop {
+ * wait for request
+ * create new job
+ * } while (!time to exit)
+ * - Close all listeners
+ * - Wait for all threads to complete
+ * - Exit
+ */
+
+ allowed_globals.jobsemaphore = create_semaphore(0);
+ allowed_globals.jobmutex = create_mutex(NULL);
+
+ /* spawn off the threads */
+ child_handles = (thread *)alloca(nthreads * sizeof(int));
+ {
+ int i;
+
+ for(i=0; i<nthreads; i++)
+ {
+ child_handles[i] = create_thread((void (*)(void *))child_main, (void *)i);
+ }
+ }
+
+ /* main loop */
+ for(;;)
+ {
+ if(max_jobs_per_exe && (total_jobs > max_jobs_per_exe) && !start_exit)
+ {
+ start_exit = 1;
+ wait_time = 1;
+ count_down = max_jobs_after_exit_request;
+ release_mutex(start_mutex);
+ start_mutex_released = 1;
+ /* set the listen queue to 1 */
+ {
+ if (listeners == NULL) {
+ listen(sd, 1);
+ }
+ else {
+ listen_rec *lr;
+
+ for (lr=listeners; lr != NULL; lr=lr->next)
+ {
+ if(lr->used)
+ {
+ listen(lr->fd, 1);
+ }
+ }
+ }
+ }
+ }
+ if(!start_exit)
+ {
+ rv = WaitForSingleObject(exit_event, 0);
+ assert((rv == WAIT_TIMEOUT) || (rv == WAIT_OBJECT_0));
+ if(rv == WAIT_OBJECT_0)
+ break;
+ rv = WaitForMultipleObjects(nthreads, child_handles, 0, 0);
+ if(rv != WAIT_TIMEOUT)
+ {
+ rv = rv - WAIT_OBJECT_0;
+ assert((rv >= 0) && (rv < nthreads));
+ cleanup_thread(child_handles, &nthreads, rv);
+ break;
+ }
+ }
+ if(start_exit && max_jobs_after_exit_request && (count_down-- < 0))
+ break;
+ tv.tv_sec = wait_time;
+ tv.tv_usec = 0;
+
+ memcpy(&main_fds, &listenfds, sizeof(fd_set));
+ #ifdef SELECT_NEEDS_CAST
+ srv = select(listenmaxfd+1, (int*)&main_fds, NULL, NULL, &tv);
+ #else
+ srv = select(listenmaxfd+1, &main_fds, NULL, NULL, &tv);
+ #endif
+ #ifdef WIN32
+ if(srv == SOCKET_ERROR)
+ errno = WSAGetLastError() - WSABASEERR;
+ #endif /* WIN32 */
+
+ if (srv < 0 && errno != EINTR)
+ log_unixerr("select", "(listen)", NULL, server_conf);
+
+ if (srv < 0)
+ continue;
+ if(srv == 0)
+ {
+ if(start_exit)
+ break;
+ else
+ continue;
+ }
+
+ if (listeners != NULL) {
+ listen_rec *lr;
+ int fd;
+
+ for (lr=listeners; lr != NULL; lr=lr->next)
+ {
+ if(!lr->used)
+ continue;
+ fd=lr->fd;
+
+ FD_ISSET(fd, &listenfds);
+ sd = fd;
+ break;
+ }
+ }
+
+ do {
+ clen = sizeof(sa_client);
+ csd = accept(sd, (struct sockaddr *)&sa_client, &clen);
+ #ifdef WIN32
+ if(csd == SOCKET_ERROR)
+ {
+ csd = -1;
+ errno = WSAGetLastError() - WSABASEERR;
+ }
+ #endif /* WIN32 */
+ } while (csd < 0 && errno == EINTR);
+
+ if (csd < 0) {
+
+ #if defined(EPROTO) && defined(ECONNABORTED)
+ if ((errno != EPROTO) && (errno != ECONNABORTED))
+ #elif defined(EPROTO)
+ if (errno != EPROTO)
+ #elif defined(ECONNABORTED)
+ if (errno != ECONNABORTED)
+ #endif
+ log_unixerr("accept", "(client socket)", NULL, server_conf);
+ }
+ else
+ {
+ add_job(csd);
+ total_jobs++;
+ }
+ }
+
+ /* Get ready to shutdown and exit */
+ allowed_globals.exit_now = 1;
+ if(!start_mutex_released)
+ {
+ release_mutex(start_mutex);
+ }
+
+ {
+ if (listeners == NULL) {
+ closesocket(sd);
+ }
+ else {
+ listen_rec *lr;
+
+ for (lr=listeners; lr != NULL; lr=lr->next)
+ {
+ if(lr->used)
+ {
+ closesocket(lr->fd);
+ lr->fd = -1;
+ }
+ }
+ }
+ }
+
+ for(i=0; i<nthreads; i++)
+ {
+ add_job(-1);
+ }
+
+ /* Wait for all your children */
+ end_time = time(NULL) + 180;
+ while(nthreads)
+ {
+ rv = WaitForMultipleObjects(nthreads, child_handles, 0, (end_time-time(NULL))*1000);
+ if(rv != WAIT_TIMEOUT)
+ {
+ rv = rv - WAIT_OBJECT_0;
+ assert((rv >= 0) && (rv < nthreads));
+ cleanup_thread(child_handles, &nthreads, rv);
+ continue;
+ }
+ break;
+ }
+
+ for(i=0; i<nthreads; i++)
+ {
+ kill_thread(child_handles[i]);
+ free_thread(child_handles[i]);
+ }
+ destroy_semaphore(allowed_globals.jobsemaphore);
+ destroy_mutex(allowed_globals.jobmutex);
+ cleanup_scoreboard();
+ exit(0);
+
+
+ } /* standalone_main */
+
+
+ int
+ create_event_and_spawn(int argc, char **argv, event **ev, int *child_num, char* prefix)
+ {
+ int pid = getpid();
+ char buf[40], mod[200];
+ int i, rv;
+ char **pass_argv = (char **)alloca(sizeof(char *)*(argc+3));
+
+ sprintf(buf, "%s_%d", prefix, ++(*child_num));
+ _flushall();
+ *ev = create_event(0, 0, buf);
+ assert(*ev);
+ pass_argv[0] = argv[0];
+ pass_argv[1] = "-c";
+ pass_argv[2] = buf;
+ for(i=1; i<argc; i++)
+ {
+ pass_argv[i+2] = argv[i];
+ }
+ pass_argv[argc+2] = NULL;
+
+
+ GetModuleFileName(NULL, mod, 200);
+ rv = spawnv(_P_NOWAIT, mod, pass_argv);
+
+ return(rv);
+ }
+
+
+ static int service_pause = 0;
+ static int service_stop = 0;
+
+
+ int
+ master_main(int argc, char **argv)
+ {
+ /*
+ * 1. Create exit events for children
+ * 2. Spawn children
+ * 3. Wait for either of your children to die
+ * 4. Close hand to dead child & its event
+ * 5. Respawn that child
+ */
+
+ int nchild = daemons_to_start;
+ event **ev;
+ int *child;
+ int child_num = 0;
+ int rv, cld;
+ char buf[100];
+ int i;
+ time_t tmstart;
+
+ sprintf(buf, "Apache%d", getpid());
+ start_mutex = create_mutex(buf);
+ ev = (event **)alloca(sizeof(event *)*nchild);
+ child = (int *)alloca(sizeof(int)*nchild);
+ for(i=0; i<nchild; i++)
+ {
+ service_set_status(SERVICE_START_PENDING);
+ child[i] = create_event_and_spawn(argc, argv, &ev[i], &child_num, buf);
+ assert(child[i]);
+ }
+ service_set_status(SERVICE_RUNNING);
+
+ for(;!service_stop;)
+ {
+ rv = WaitForMultipleObjects(nchild, (HANDLE *)child, FALSE, 2000);
+ assert(rv != WAIT_FAILED);
+ if(rv == WAIT_TIMEOUT)
+ continue;
+ cld = rv - WAIT_OBJECT_0;
+ assert(rv < nchild);
+ CloseHandle((HANDLE)child[rv]);
+ CloseHandle(ev[rv]);
+ child[rv] = create_event_and_spawn(argc, argv, &ev[rv], &child_num, buf);
+ assert(child[rv]);
+ }
+
+ /*
+ * Tell all your kids to stop. Wait for them for some time
+ * Kill those that haven't yet stopped
+ */
+ for(i=0; i<nchild; i++)
+ {
+ SetEvent(ev[i]);
+ }
+
+ for(tmstart=time(NULL); nchild && (tmstart < (time(NULL) + 60));)
+ {
+ service_set_status(SERVICE_STOP_PENDING);
+ rv = WaitForMultipleObjects(nchild, (HANDLE *)child, FALSE, 2000);
+ assert(rv != WAIT_FAILED);
+ if(rv == WAIT_TIMEOUT)
+ continue;
+ cld = rv - WAIT_OBJECT_0;
+ assert(rv < nchild);
+ CloseHandle((HANDLE)child[rv]);
+ CloseHandle(ev[rv]);
+ for(i=rv; i<(nchild-1); i++)
+ {
+ child[i] = child[i+1];
+ ev[i] = ev[i+1];
+ }
+ nchild--;
+ }
+ for(i=0; i<nchild; i++)
+ {
+ TerminateProcess((HANDLE)child[i], 1);
+ }
+ service_set_status(SERVICE_STOPPED);
+
+
+ destroy_mutex(start_mutex);
+ return(0);
+ }
+
+
+
+
+
+
+ int
+ main(int argc, char *argv[])
+ {
+ int c;
+ int child = 0;
+ char *cp;
+ int run_as_service = 1;
+ int install = 0;
+
+ #ifdef AUX
+ (void)set42sig();
+ #endif
+
+ #ifdef SecureWare
+ if(set_auth_parameters(argc,argv) < 0)
+ perror("set_auth_parameters");
+ if(getluid() < 0)
+ if(setluid(getuid()) < 0)
+ perror("setluid");
+ if(setreuid(0, 0) < 0)
+ perror("setreuid");
+ #endif
+
+ #ifdef WIN32
+ /* Initialize the stupid sockets */
+ AMCSocketInitialize();
+ #endif /* WIN32 */
+
+ init_alloc();
+ pconf = permanent_pool;
+ ptrans = make_sub_pool(pconf);
+
+ server_argv0 = argv[0];
+ strncpy (server_root, HTTPD_ROOT, sizeof(server_root)-1);
+ server_root[sizeof(server_root)-1] = '\0';
+ strncpy (server_confname, SERVER_CONFIG_FILE, sizeof(server_root)-1);
+ server_confname[sizeof(server_confname)-1] = '\0';
+
+ while((c = getopt(argc,argv,"Xd:f:vhlc:ius")) != -1) {
+ switch(c) {
+ #ifdef WIN32
+ case 'c':
+ exit_event = open_event(optarg);
+ cp = strchr(optarg, '_');
+ assert(cp);
+ *cp = 0;
+ start_mutex = open_mutex(optarg);
+ child = 1;
+ break;
+ case 'i':
+ install = 1;
+ break;
+ case 'u':
+ install = -1;
+ break;
+ case 's':
+ run_as_service = 0;
+ break;
+ #endif /* WIN32 */
+ case 'd':
+ strncpy (server_root, optarg, sizeof(server_root)-1);
+ server_root[sizeof(server_root)-1] = '\0';
+ break;
+ case 'f':
+ strncpy (server_confname, optarg, sizeof(server_confname)-1);
+ server_confname[sizeof(server_confname)-1] = '\0';
+ break;
+ case 'v':
+ printf("Server version %s.\n",SERVER_VERSION);
+ exit(0);
+ case 'h':
+ show_directives();
+ exit(0);
+ case 'l':
+ show_modules();
+ exit(0);
+ case 'X':
+ ++one_process; /* Weird debugging mode. */
+ break;
+ case '?':
+ usage(argv[0]);
+ }
+ }
+
+ #ifdef __EMX__
+ printf("%s \n",SERVER_VERSION);
+ printf("OS/2 port by Garey Smiley <ga...@slink.com> \n");
+ #endif
+ #ifdef WIN32
+ if(!child)
+ {
+ printf("%s \n",SERVER_VERSION);
+ printf("WIN32 port by Ambarish Malpani <am...@valicert.com> and the Apache Group.\n");
+ }
+ #endif
+ if(!child && run_as_service)
+ {
+ service_cd();
+ }
+ setup_prelinked_modules();
+
+ server_conf = read_config (pconf, ptrans, server_confname);
+ suexec_enabled = init_suexec();
+ open_logs(server_conf, pconf);
+ set_group_privs();
+
+ if(one_process && !exit_event)
+ exit_event = create_event(0, 0, NULL);
+ if(one_process && !start_mutex)
+ start_mutex = create_mutex(NULL);
+ /*
+ * In the future, the main will spawn off a couple
+ * of children and monitor them. As soon as a child
+ * exits, it spawns off a new one
+ */
+ if(child || one_process)
+ {
+ if(!exit_event || !start_mutex)
+ exit(-1);
+ worker_main();
+ destroy_mutex(start_mutex);
+ destroy_event(exit_event);
+ }
+ else
+ {
+ service_main(master_main, argc, argv,
+ &service_pause, &service_stop, "Apache", install, run_as_service);
+ }
+
+ return(0);
+ }
+
+
+ #endif /* ndef MULTITHREAD */
1.11 +2 -0 apache/src/http_main.h
Index: http_main.h
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -C3 -r1.10 -r1.11
*** http_main.h 1997/04/26 20:20:06 1.10
--- http_main.h 1997/06/15 19:22:26 1.11
***************
*** 97,99 ****
--- 97,101 ----
int count_busy_servers ();
int count_idle_servers ();
+ unsigned int set_callback_and_alarm(void (*fn)(int), int x);
+ int check_alarm();
1.127 +5 -3 apache/src/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.126
retrieving revision 1.127
diff -C3 -r1.126 -r1.127
*** http_protocol.c 1997/05/29 03:44:31 1.126
--- http_protocol.c 1997/06/15 19:22:27 1.127
***************
*** 503,509 ****
{
const char *s;
! #ifdef __EMX__
/* Variable for OS/2 fix below. */
int loop;
#endif
--- 503,509 ----
{
const char *s;
! #if defined(__EMX__) || defined(WIN32)
/* Variable for OS/2 fix below. */
int loop;
#endif
***************
*** 527,533 ****
r->proxyreq = 0;
r->uri = getword (r->pool, &uri, '?');
! #ifdef __EMX__
/* Handle path translations for OS/2 and plug security hole. */
/* This will prevent "http://www.wherever.com/..\..\/" from
returning a directory for the root drive. */
--- 527,533 ----
r->proxyreq = 0;
r->uri = getword (r->pool, &uri, '?');
! #if defined(__EMX__) || defined(WIN32)
/* Handle path translations for OS/2 and plug security hole. */
/* This will prevent "http://www.wherever.com/..\..\/" from
returning a directory for the root drive. */
***************
*** 627,633 ****
--- 627,635 ----
}
}
/* we've probably got something to do, ignore graceful restart requests */
+ #ifdef SIGUSR1
signal (SIGUSR1, SIG_IGN);
+ #endif /* SIGUSR1 */
bsetflag( conn->client, B_SAFEREAD, 0 );
if (len == (HUGE_STRING_LEN - 1)) {
log_printf(r->server, "request failed for %s, reason: URI too long",
***************
*** 1209,1215 ****
"byteranges; boundary=", r->boundary, NULL));
else if (r->content_type)
table_set(r->headers_out, "Content-Type", r->content_type);
! else
table_set(r->headers_out, "Content-Type", default_type(r));
if (r->content_encoding)
--- 1211,1217 ----
"byteranges; boundary=", r->boundary, NULL));
else if (r->content_type)
table_set(r->headers_out, "Content-Type", r->content_type);
! else
table_set(r->headers_out, "Content-Type", default_type(r));
if (r->content_encoding)
1.51 +8 -8 apache/src/http_request.c
Index: http_request.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_request.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -C3 -r1.50 -r1.51
*** http_request.c 1997/05/14 19:22:52 1.50
--- http_request.c 1997/06/15 19:22:27 1.51
***************
*** 86,100 ****
*/
int check_symlinks (char *d, int opts)
! {
! struct stat lfi, fi;
! char *lastp;
! int res;
!
! #ifdef __EMX__
/* OS/2 dosen't have symlinks */
return OK;
#else
if (opts & OPT_SYM_LINKS) return OK;
--- 86,100 ----
*/
int check_symlinks (char *d, int opts)
! {
! #if defined(__EMX__) || defined(WIN32)
/* OS/2 dosen't have symlinks */
return OK;
#else
+ struct stat lfi, fi;
+ char *lastp;
+ int res;
+
if (opts & OPT_SYM_LINKS) return OK;
***************
*** 259,265 ****
* for the moment, that's not worth the trouble.
*/
! #ifdef __EMX__
/* Add OS/2 drive name support */
if ((test_filename[0] != '/') && (test_filename[1] != ':'))
#else
--- 259,265 ----
* for the moment, that's not worth the trouble.
*/
! #if defined(__EMX__) || defined(WIN32)
/* Add OS/2 drive name support */
if ((test_filename[0] != '/') && (test_filename[1] != ':'))
#else
***************
*** 763,769 ****
}
r->status = type;
!
/* Two types of custom redirects --- plain text, and URLs.
* Plain text has a leading '"', so the URL code, here, is triggered
* on its absence
--- 763,769 ----
}
r->status = type;
!
/* Two types of custom redirects --- plain text, and URLs.
* Plain text has a leading '"', so the URL code, here, is triggered
* on its absence
1.113 +4 -1 apache/src/httpd.h
Index: httpd.h
===================================================================
RCS file: /export/home/cvs/apache/src/httpd.h,v
retrieving revision 1.112
retrieving revision 1.113
diff -C3 -r1.112 -r1.113
*** httpd.h 1997/06/06 13:51:10 1.112
--- httpd.h 1997/06/15 19:22:28 1.113
***************
*** 171,177 ****
/* The path to the Bourne shell, for parsed docs */
#ifndef SHELL_PATH
! #ifdef __EMX__
/* Set default for OS/2 file system */
#define SHELL_PATH "CMD.EXE"
#else
--- 171,177 ----
/* The path to the Bourne shell, for parsed docs */
#ifndef SHELL_PATH
! #if defined(__EMX__) || defined(WIN32)
/* Set default for OS/2 file system */
#define SHELL_PATH "CMD.EXE"
#else
***************
*** 236,241 ****
--- 236,244 ----
*/
#define DEFAULT_MAX_REQUESTS_PER_CHILD 0
+
+ #define DEFAULT_THREADS_PER_CHILD 50
+ #define DEFAULT_EXCESS_REQUESTS_PER_CHILD 0
/* If you have altered Apache and wish to change the SERVER_VERSION
* identifier below, please keep to the HTTP specification. This states that
1.16 +1 -1 apache/src/mod_alias.c
Index: mod_alias.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_alias.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -C3 -r1.15 -r1.16
*** mod_alias.c 1997/04/14 01:09:13 1.15
--- mod_alias.c 1997/06/15 19:22:28 1.16
***************
*** 263,269 ****
char *ret;
int status;
! #ifdef __EMX__
/* Add support for OS/2 drive names */
if ((r->uri[0] != '/' && r->uri[0] != '\0') && r->uri[1] != ':')
#else
--- 263,269 ----
char *ret;
int status;
! #if defined(__EMX__) || defined(WIN32)
/* Add support for OS/2 drive names */
if ((r->uri[0] != '/' && r->uri[0] != '\0') && r->uri[1] != ':')
#else
1.40 +16 -7 apache/src/mod_cgi.c
Index: mod_cgi.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -C3 -r1.39 -r1.40
*** mod_cgi.c 1997/04/21 20:29:09 1.39
--- mod_cgi.c 1997/06/15 19:22:28 1.40
***************
*** 272,283 ****
char *argv0;
};
! void cgi_child (void *child_stuff)
{
struct cgi_child_stuff *cld = (struct cgi_child_stuff *)child_stuff;
request_rec *r = cld->r;
char *argv0 = cld->argv0;
int nph = cld->nph;
#ifdef DEBUG_CGI
#ifdef __EMX__
--- 272,284 ----
char *argv0;
};
! static int cgi_child (void *child_stuff)
{
struct cgi_child_stuff *cld = (struct cgi_child_stuff *)child_stuff;
request_rec *r = cld->r;
char *argv0 = cld->argv0;
int nph = cld->nph;
+ int child_pid;
#ifdef DEBUG_CGI
#ifdef __EMX__
***************
*** 309,315 ****
if (!cld->debug)
error_log2stderr (r->server);
! #ifndef __EMX__
if (nph) client_to_stdout (r->connection);
#endif
--- 310,316 ----
if (!cld->debug)
error_log2stderr (r->server);
! #if !defined(__EMX__) && !defined(WIN32)
if (nph) client_to_stdout (r->connection);
#endif
***************
*** 319,325 ****
cleanup_for_exec();
! call_exec(r, argv0, env, 0);
/* Uh oh. Still here. Where's the kaboom? There was supposed to be an
* EARTH-shattering kaboom!
--- 320,329 ----
cleanup_for_exec();
! child_pid = call_exec(r, argv0, env, 0);
! #ifdef WIN32
! return(child_pid);
! #else
/* Uh oh. Still here. Where's the kaboom? There was supposed to be an
* EARTH-shattering kaboom!
***************
*** 336,341 ****
--- 340,348 ----
"exec of %s failed, errno is %d\n", r->filename, errno);
write(2, err_string, strlen(err_string));
exit(0);
+ /* NOT REACHED */
+ return(0);
+ #endif
}
int cgi_handler (request_rec *r)
***************
*** 375,381 ****
if (S_ISDIR(r->finfo.st_mode))
return log_scripterror(r, conf, FORBIDDEN,
"attempt to invoke directory as script");
! #ifdef __EMX__
/* Allow for cgi files without the .EXE extension on them under OS/2 */
if (r->finfo.st_mode == 0) {
struct stat statbuf;
--- 382,388 ----
if (S_ISDIR(r->finfo.st_mode))
return log_scripterror(r, conf, FORBIDDEN,
"attempt to invoke directory as script");
! #if defined(__EMX__) || defined(WIN32)
/* Allow for cgi files without the .EXE extension on them under OS/2 */
if (r->finfo.st_mode == 0) {
struct stat statbuf;
***************
*** 414,420 ****
spawn_child_err (r->main ? r->main->pool : r->pool, cgi_child,
(void *)&cld,
nph ? just_wait : kill_after_timeout,
! #ifdef __EMX__
&script_out, &script_in, &script_err))) {
#else
&script_out, nph ? NULL : &script_in,
--- 421,427 ----
spawn_child_err (r->main ? r->main->pool : r->pool, cgi_child,
(void *)&cld,
nph ? just_wait : kill_after_timeout,
! #if defined(__EMX__) || defined(WIN32)
&script_out, &script_in, &script_err))) {
#else
&script_out, nph ? NULL : &script_in,
***************
*** 434,440 ****
*/
if (should_client_block(r)) {
! void (*handler)();
int dbsize, len_read;
if (conf->logname) {
--- 441,447 ----
*/
if (should_client_block(r)) {
! void (*handler)(int);
int dbsize, len_read;
if (conf->logname) {
***************
*** 443,449 ****
--- 450,458 ----
}
hard_timeout ("copy script args", r);
+ #ifdef SIGPIPE
handler = signal (SIGPIPE, SIG_IGN);
+ #endif
while ((len_read =
get_client_block(r, argsbuffer, HUGE_STRING_LEN)) > 0)
***************
*** 536,542 ****
}
if (nph) {
! #ifdef __EMX__
while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL) {
bputs(argsbuffer, r->connection->client);
}
--- 545,551 ----
}
if (nph) {
! #if defined(__EMX__) || defined(WIN32)
while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_in) != NULL) {
bputs(argsbuffer, r->connection->client);
}
1.27 +4 -0 apache/src/mod_dir.c
Index: mod_dir.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_dir.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -C3 -r1.26 -r1.27
*** mod_dir.c 1997/05/13 04:01:50 1.26
--- mod_dir.c 1997/06/15 19:22:29 1.27
***************
*** 68,73 ****
--- 68,77 ----
#include "http_main.h"
#include "util_script.h"
+ #ifdef WIN32
+ #include "nt/readdir.h"
+ #endif
+
module dir_module;
/****************************************************************
1.34 +15 -5 apache/src/mod_include.c
Index: mod_include.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_include.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -C3 -r1.33 -r1.34
*** mod_include.c 1997/06/05 00:57:45 1.33
--- mod_include.c 1997/06/15 19:22:29 1.34
***************
*** 104,110 ****
--- 104,112 ----
void add_include_vars(request_rec *r, char *timefmt)
{
+ #ifndef WIN32
struct passwd *pw;
+ #endif /* ndef WIN32 */
table *e = r->subprocess_env;
char *t;
time_t date = r->request_time;
***************
*** 114,119 ****
--- 116,122 ----
table_set(e, "LAST_MODIFIED",ht_time(r->pool,r->finfo.st_mtime,timefmt,0));
table_set(e, "DOCUMENT_URI", r->uri);
table_set(e, "DOCUMENT_PATH_INFO", r->path_info);
+ #ifndef WIN32
pw = getpwuid(r->finfo.st_uid);
if (pw) {
table_set(e, "USER_NAME", pw->pw_name);
***************
*** 122,127 ****
--- 125,131 ----
ap_snprintf(uid, sizeof(uid), "user#%lu", (unsigned long)r->finfo.st_uid);
table_set(e, "USER_NAME", uid);
}
+ #endif /* ndef WIN32 */
if((t = strrchr(r->filename, '/')))
table_set (e, "DOCUMENT_NAME", ++t);
***************
*** 590,600 ****
char *s;
} include_cmd_arg;
! void include_cmd_child (void *arg)
{
request_rec *r = ((include_cmd_arg *)arg)->r;
char *s = ((include_cmd_arg *)arg)->s;
table *env = r->subprocess_env;
#ifdef DEBUG_INCLUDE_CMD
FILE *dbg = fopen ("/dev/tty", "w");
#endif
--- 594,605 ----
char *s;
} include_cmd_arg;
! int include_cmd_child (void *arg)
{
request_rec *r = ((include_cmd_arg *)arg)->r;
char *s = ((include_cmd_arg *)arg)->s;
table *env = r->subprocess_env;
+ int child_pid = 0;
#ifdef DEBUG_INCLUDE_CMD
FILE *dbg = fopen ("/dev/tty", "w");
#endif
***************
*** 636,643 ****
#endif
cleanup_for_exec();
/* set shellcmd flag to pass arg to SHELL_PATH */
! call_exec(r, s, create_environment (r->pool, env), 1);
!
/* Oh, drat. We're still here. The log file descriptors are closed,
* so we have to whimper a complaint onto stderr...
*/
--- 641,650 ----
#endif
cleanup_for_exec();
/* set shellcmd flag to pass arg to SHELL_PATH */
! child_pid = call_exec(r, s, create_environment (r->pool, env), 1);
! #ifdef WIN32
! return(child_pid);
! #else
/* Oh, drat. We're still here. The log file descriptors are closed,
* so we have to whimper a complaint onto stderr...
*/
***************
*** 650,655 ****
--- 657,665 ----
SHELL_PATH,errno);
write (2, err_string, strlen(err_string));
exit(0);
+ /* NOT REACHED */
+ return(child_pid);
+ #endif /* WIN32 */
}
int include_cmd(char *s, request_rec *r) {
***************
*** 1799,1805 ****
}
if (*state == xbithack_full
! #ifndef __EMX__
/* OS/2 dosen't support Groups. */
&& (r->finfo.st_mode & S_IXGRP)
#endif
--- 1809,1815 ----
}
if (*state == xbithack_full
! #if !defined(__EMX__) && !defined(WIN32)
/* OS/2 dosen't support Groups. */
&& (r->finfo.st_mode & S_IXGRP)
#endif
***************
*** 1845,1851 ****
{
enum xbithack *state;
! #ifdef __EMX__
/* OS/2 dosen't currently support the xbithack. This is being worked on. */
return DECLINED;
#else
--- 1855,1861 ----
{
enum xbithack *state;
! #if defined(__EMX__) || defined(WIN32)
/* OS/2 dosen't currently support the xbithack. This is being worked on. */
return DECLINED;
#else
1.17 +5 -0 apache/src/mod_info.c
Index: mod_info.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_info.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -C3 -r1.16 -r1.17
*** mod_info.c 1997/04/12 04:24:59 1.16
--- mod_info.c 1997/06/15 19:22:30 1.17
***************
*** 76,81 ****
--- 76,82 ----
#include "http_main.h"
#include "http_protocol.h"
#include "util_script.h"
+ #include "http_conf_globals.h"
typedef struct mod_info_config_lines {
char *cmd;
***************
*** 318,323 ****
--- 319,328 ----
rputs(buf,r);
ap_snprintf(buf, sizeof(buf), "<strong>Max Requests:</strong> <tt>per child: %d keep alive: %s max per connection: %d</tt><br>\n",max_requests_per_child,serv->keep_alive ? "on":"off", serv->keep_alive_max);
rputs(buf,r);
+ ap_snprintf(buf, sizeof(buf), "<strong>Threads:</strong> <tt>per child: %d </tt><br>\n",threads_per_child);
+ rputs(buf,r);
+ ap_snprintf(buf, sizeof(buf), "<strong>Excess requests:</strong> <tt>per child: %d </tt><br>\n",excess_requests_per_child);
+ rputs(buf,r);
ap_snprintf(buf, sizeof(buf), "<strong>Timeouts:</strong> <tt>connection: %d keep-alive: %d</tt><br>",serv->timeout,serv->keep_alive_timeout);
rputs(buf,r);
ap_snprintf(buf, sizeof(buf), "<strong>Server Root:</strong> <tt>%s</tt><br>\n",server_root);
1.12 +8 -3 apache/src/mod_log_agent.c
Index: mod_log_agent.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_log_agent.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C3 -r1.11 -r1.12
*** mod_log_agent.c 1997/03/22 23:51:02 1.11
--- mod_log_agent.c 1997/06/15 19:22:30 1.12
***************
*** 96,111 ****
{ NULL }
};
! void agent_log_child (void *cmd)
{
/* Child process code for 'AgentLog "|..."';
* may want a common framework for this, since I expect it will
* be common for other foo-loggers to want this sort of thing...
*/
!
cleanup_for_exec();
signal (SIGHUP, SIG_IGN);
! #ifdef __EMX__
/* For OS/2 we need to use a '/' */
execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
--- 96,115 ----
{ NULL }
};
! static int agent_log_child (void *cmd)
{
/* Child process code for 'AgentLog "|..."';
* may want a common framework for this, since I expect it will
* be common for other foo-loggers to want this sort of thing...
*/
! int child_pid = 0;
!
cleanup_for_exec();
signal (SIGHUP, SIG_IGN);
! #if defined(WIN32)
! child_pid = spawnl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
! return(child_pid);
! #elif defined(__EMX__)
/* For OS/2 we need to use a '/' */
execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
***************
*** 114,119 ****
--- 118,124 ----
perror ("exec");
fprintf (stderr, "Exec of shell for logging failed!!!\n");
exit (1);
+ return(child_pid);
}
void open_agent_log (server_rec *s, pool *p)
1.29 +11 -4 apache/src/mod_log_config.c
Index: mod_log_config.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_log_config.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -C3 -r1.28 -r1.29
*** mod_log_config.c 1997/05/04 20:47:47 1.28
--- mod_log_config.c 1997/06/15 19:22:30 1.29
***************
*** 165,171 ****
module config_log_module;
static int xfer_flags = ( O_WRONLY | O_APPEND | O_CREAT );
! #ifdef __EMX__
/* OS/2 dosen't support users and groups */
static mode_t xfer_mode = ( S_IREAD | S_IWRITE );
#else
--- 165,171 ----
module config_log_module;
static int xfer_flags = ( O_WRONLY | O_APPEND | O_CREAT );
! #if defined(__EMX__) || defined(WIN32)
/* OS/2 dosen't support users and groups */
static mode_t xfer_mode = ( S_IREAD | S_IWRITE );
#else
***************
*** 673,688 ****
{ NULL }
};
! void config_log_child (void *cmd)
{
/* Child process code for 'TransferLog "|..."';
* may want a common framework for this, since I expect it will
* be common for other foo-loggers to want this sort of thing...
*/
!
cleanup_for_exec();
signal (SIGHUP, SIG_IGN);
! #ifdef __EMX__
/* For OS/2 we need to use a '/' */
execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
--- 673,694 ----
{ NULL }
};
! static int config_log_child (void *cmd)
{
/* Child process code for 'TransferLog "|..."';
* may want a common framework for this, since I expect it will
* be common for other foo-loggers to want this sort of thing...
*/
! int child_pid = 0;
!
cleanup_for_exec();
+ #ifdef SIGHUP
signal (SIGHUP, SIG_IGN);
! #endif
! #if defined(WIN32)
! child_pid = spawnl (_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
! return(child_pid);
! #elif defined(__EMX__)
/* For OS/2 we need to use a '/' */
execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
***************
*** 691,696 ****
--- 697,703 ----
perror ("exec");
fprintf (stderr, "Exec of shell for logging failed!!!\n");
exit (1);
+ return(child_pid);
}
config_log_state *open_config_log (server_rec *s, pool *p,
1.12 +9 -3 apache/src/mod_log_referer.c
Index: mod_log_referer.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_log_referer.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C3 -r1.11 -r1.12
*** mod_log_referer.c 1997/03/22 23:51:03 1.11
--- mod_log_referer.c 1997/06/15 19:22:30 1.12
***************
*** 110,125 ****
{ NULL }
};
! void referer_log_child (void *cmd)
{
/* Child process code for 'RefererLog "|..."';
* may want a common framework for this, since I expect it will
* be common for other foo-loggers to want this sort of thing...
*/
!
cleanup_for_exec();
signal (SIGHUP, SIG_IGN);
! #ifdef __EMX__
/* For OS/2 we need to use a '/' */
execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
--- 110,130 ----
{ NULL }
};
! static int referer_log_child (void *cmd)
{
/* Child process code for 'RefererLog "|..."';
* may want a common framework for this, since I expect it will
* be common for other foo-loggers to want this sort of thing...
*/
! int child_pid = 0;
!
cleanup_for_exec();
signal (SIGHUP, SIG_IGN);
! #if defined(WIN32)
! /* For OS/2 we need to use a '/' */
! child_pid = spawnl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
! return(child_pid);
! #elif defined(__EMX__)
/* For OS/2 we need to use a '/' */
execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
***************
*** 128,133 ****
--- 133,139 ----
perror ("execl");
fprintf (stderr, "Exec of shell for logging failed!!!\n");
exit (1);
+ return(child_pid);
}
void open_referer_log (server_rec *s, pool *p)
1.41 +4 -1 apache/src/mod_negotiation.c
Index: mod_negotiation.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_negotiation.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -C3 -r1.40 -r1.41
*** mod_negotiation.c 1997/04/17 02:50:20 1.40
--- mod_negotiation.c 1997/06/15 19:22:31 1.41
***************
*** 63,68 ****
--- 63,71 ----
#include "http_core.h"
#include "http_log.h"
#include "util_script.h"
+ #ifdef WIN32
+ #include "nt/readdir.h"
+ #endif
/* define TCN_02 to allow for Holtman I-D transparent negotiation.
* This file currently implements the draft-02, except for
***************
*** 678,684 ****
set_mime_fields (&mime_info, &accept_info);
}
else if (!strncmp (buffer, "content-length:", 15)) {
! mime_info.bytes = atoi(body);
}
else if (!strncmp (buffer, "content-language:", 17)) {
mime_info.content_languages =
--- 681,687 ----
set_mime_fields (&mime_info, &accept_info);
}
else if (!strncmp (buffer, "content-length:", 15)) {
! mime_info.bytes = atof(body);
}
else if (!strncmp (buffer, "content-language:", 17)) {
mime_info.content_languages =
1.29 +19 -5 apache/src/mod_rewrite.c
Index: mod_rewrite.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_rewrite.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -C3 -r1.28 -r1.29
*** mod_rewrite.c 1997/04/24 23:35:22 1.28
--- mod_rewrite.c 1997/06/15 19:22:31 1.29
***************
*** 100,106 ****
--- 100,108 ----
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+ #ifndef WIN32
#include <netinet/in.h>
+ #endif
/* from the Apache server ... */
#include "httpd.h"
***************
*** 1684,1690 ****
rc = 1;
}
else if (strcmp(p->pattern, "-l") == 0) {
! #ifndef __EMX__
/* OS/2 dosen't support links. */
if (stat(input, &sb) == 0)
if (S_ISLNK(sb.st_mode))
--- 1686,1692 ----
rc = 1;
}
else if (strcmp(p->pattern, "-l") == 0) {
! #if !defined(__EMX__) && !defined(WIN32)
/* OS/2 dosen't support links. */
if (stat(input, &sb) == 0)
if (S_ISLNK(sb.st_mode))
***************
*** 2278,2294 ****
}
/* Child process code for 'RewriteLog "|..."' */
! static void rewritelog_child(void *cmd)
{
cleanup_for_exec();
signal(SIGHUP, SIG_IGN);
! #ifdef __EMX__
/* OS/2 needs a '/' */
execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
exit(1);
}
static void rewritelog(request_rec *r, int level, const char *text, ...)
--- 2280,2302 ----
}
/* Child process code for 'RewriteLog "|..."' */
! static int rewritelog_child(void *cmd)
{
+ int child_pid = 0;
+
cleanup_for_exec();
signal(SIGHUP, SIG_IGN);
! #if defined(WIN32)
! child_pid = spawnl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
! return(child_pid);
! #elif defined(__EMX__)
/* OS/2 needs a '/' */
execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
exit(1);
+ return(child_pid);
}
static void rewritelog(request_rec *r, int level, const char *text, ...)
***************
*** 2425,2441 ****
}
/* child process code */
! static void rewritemap_program_child(void *cmd)
{
cleanup_for_exec();
signal(SIGHUP, SIG_IGN);
! #ifdef __EMX__
/* OS/2 needs a '/' */
execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
exit(1);
}
--- 2433,2455 ----
}
/* child process code */
! static int rewritemap_program_child(void *cmd)
{
+ int child_pid = 0;
+
cleanup_for_exec();
signal(SIGHUP, SIG_IGN);
! #if defined(WIN32)
! child_pid = spawnl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
! return(child_pid);
! #elif defined(__EMX__)
/* OS/2 needs a '/' */
execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL);
#else
execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL);
#endif
exit(1);
+ return(0);
}
1.23 +1 -1 apache/src/mod_rewrite.h
Index: mod_rewrite.h
===================================================================
RCS file: /export/home/cvs/apache/src/mod_rewrite.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -C3 -r1.22 -r1.23
*** mod_rewrite.h 1997/04/17 02:52:51 1.22
--- mod_rewrite.h 1997/06/15 19:22:32 1.23
***************
*** 122,128 ****
#endif
#if !defined(USE_FCNTL) && !defined(USE_FLOCK)
#define USE_FLOCK 1
! #ifndef MPE
#include <sys/file.h>
#endif
#ifndef LOCK_UN
--- 122,128 ----
#endif
#if !defined(USE_FCNTL) && !defined(USE_FLOCK)
#define USE_FLOCK 1
! #if !defined(MPE) && !defined(WIN32)
#include <sys/file.h>
#endif
#ifndef LOCK_UN
1.15 +17 -2 apache/src/mod_userdir.c
Index: mod_userdir.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_userdir.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -C3 -r1.14 -r1.15
*** mod_userdir.c 1997/03/07 14:15:44 1.14
--- mod_userdir.c 1997/06/15 19:22:32 1.15
***************
*** 142,155 ****
if (strchr(userdir, '*'))
x = getword(r->pool, &userdir, '*');
! #ifdef __EMX__
/* Add support for OS/2 drive letters */
if ((userdir[0] == '/') || (userdir[1] == ':') || (userdir[0] == '\0')) {
#else
if ((userdir[0] == '/') || (userdir[0] == '\0')) {
#endif
if (x) {
if (strchr(x, ':')) {
redirect = pstrcat(r->pool, x, w, userdir, dname, NULL);
table_set (r->headers_out, "Location", redirect);
return REDIRECT;
--- 142,166 ----
if (strchr(userdir, '*'))
x = getword(r->pool, &userdir, '*');
! #if defined(__EMX__) || defined(WIN32)
/* Add support for OS/2 drive letters */
if ((userdir[0] == '/') || (userdir[1] == ':') || (userdir[0] == '\0')) {
#else
if ((userdir[0] == '/') || (userdir[0] == '\0')) {
#endif
if (x) {
+ #ifdef WIN32
+ /*
+ * Crummy hack. Need to figure out whether we have
+ * been redirected to a URL or to a file on some
+ * drive. Since I know of no protocols that are a
+ * single letter, if the : is the second character,
+ * I will assume a file was specified
+ */
+ if (strchr(x+2, ':')) {
+ #else
if (strchr(x, ':')) {
+ #endif /* WIN32 */
redirect = pstrcat(r->pool, x, w, userdir, dname, NULL);
table_set (r->headers_out, "Location", redirect);
return REDIRECT;
***************
*** 166,171 ****
--- 177,186 ----
return REDIRECT;
}
else {
+ #ifdef WIN32
+ /* Need to figure out home dirs on NT */
+ return DECLINED;
+ #else /* WIN32 */
struct passwd *pw;
if((pw=getpwnam(w)))
#ifdef __EMX__
***************
*** 174,180 ****
#else
filename = pstrcat (r->pool, pw->pw_dir, "/", userdir, NULL);
#endif
!
}
/* Now see if it exists, or we're at the last entry. If we are at the
--- 189,195 ----
#else
filename = pstrcat (r->pool, pw->pw_dir, "/", userdir, NULL);
#endif
! #endif /* WIN32 */
}
/* Now see if it exists, or we're at the last entry. If we are at the
1.12 +6 -6 apache/src/rfc1413.c
Index: rfc1413.c
===================================================================
RCS file: /export/home/cvs/apache/src/rfc1413.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C3 -r1.11 -r1.12
*** rfc1413.c 1997/05/29 18:29:12 1.11
--- rfc1413.c 1997/06/15 19:22:33 1.12
***************
*** 75,82 ****
#include "httpd.h" /* for server_rec, conn_rec, ap_longjmp, etc. */
#include "http_log.h" /* for log_unixerr */
#include "rfc1413.h"
! #ifndef SCO
extern char *strchr();
extern char *inet_ntoa();
#endif
--- 75,83 ----
#include "httpd.h" /* for server_rec, conn_rec, ap_longjmp, etc. */
#include "http_log.h" /* for log_unixerr */
#include "rfc1413.h"
+ #include "http_main.h" /* set_callback_and_alarm */
! #if !defined(SCO) && !defined(WIN32)
extern char *strchr();
extern char *inet_ntoa();
#endif
***************
*** 100,106 ****
JMP_BUF timebuf;
/* bind_connect - bind both ends of a socket */
!
static int
get_rfc1413(int sock, const struct sockaddr_in *our_sin,
const struct sockaddr_in *rmt_sin, char user[256], server_rec *srv)
--- 101,107 ----
JMP_BUF timebuf;
/* bind_connect - bind both ends of a socket */
! /* Ambarish fix this. Very broken */
static int
get_rfc1413(int sock, const struct sockaddr_in *our_sin,
const struct sockaddr_in *rmt_sin, char user[256], server_rec *srv)
***************
*** 209,225 ****
*/
if (ap_setjmp(timebuf) == 0)
{
! signal(SIGALRM, ident_timeout);
! alarm(rfc1413_timeout);
if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user,
srv)
>= 0)
result = user;
! alarm(0);
}
! close(sock);
conn->remote_logname = result;
return conn->remote_logname;
--- 210,225 ----
*/
if (ap_setjmp(timebuf) == 0)
{
! set_callback_and_alarm(ident_timeout, rfc1413_timeout);
if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user,
srv)
>= 0)
result = user;
! set_callback_and_alarm(NULL, 0);
}
! closesocket(sock);
conn->remote_logname = result;
return conn->remote_logname;
1.22 +2 -0 apache/src/scoreboard.h
Index: scoreboard.h
===================================================================
RCS file: /export/home/cvs/apache/src/scoreboard.h,v
retrieving revision 1.21
retrieving revision 1.22
diff -C3 -r1.21 -r1.22
*** scoreboard.h 1997/04/24 23:35:23 1.21
--- scoreboard.h 1997/06/15 19:22:34 1.22
***************
*** 50,56 ****
--- 50,58 ----
*
*/
+ #ifndef WIN32
#include <sys/times.h>
+ #endif
/* Scoreboard info on a process is, for now, kept very brief ---
* just status value and pid (the latter so that the caretaker process
1.53 +10 -2 apache/src/util.c
Index: util.c
===================================================================
RCS file: /export/home/cvs/apache/src/util.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -C3 -r1.52 -r1.53
*** util.c 1997/04/12 04:24:59 1.52
--- util.c 1997/06/15 19:22:34 1.53
***************
*** 703,709 ****
for(x=0;cmd[x];x++) {
! #ifdef __EMX__
/* Don't allow '&' in parameters under OS/2. */
/* This can be used to send commands to the shell. */
if (cmd[x] == '&') {
--- 703,709 ----
for(x=0;cmd[x];x++) {
! #if defined(__EMX__) || defined(WIN32)
/* Don't allow '&' in parameters under OS/2. */
/* This can be used to send commands to the shell. */
if (cmd[x] == '&') {
***************
*** 941,947 ****
#ifdef MULTIPLE_GROUPS
int cnt;
#endif
! #ifdef __EMX__
/* OS/2 dosen't have Users and Groups */
return 1;
#else
--- 941,947 ----
#ifdef MULTIPLE_GROUPS
int cnt;
#endif
! #if defined(__EMX__) || defined(WIN32)
/* OS/2 dosen't have Users and Groups */
return 1;
#else
***************
*** 1087,1092 ****
--- 1087,1095 ----
}
uid_t uname2id(const char *name) {
+ #ifdef WIN32
+ return(1);
+ #else
struct passwd *ent;
if(name[0] == '#')
***************
*** 1097,1105 ****
--- 1100,1112 ----
exit(1);
}
return(ent->pw_uid);
+ #endif
}
gid_t gname2id(const char *name) {
+ #ifdef WIN32
+ return(1);
+ #else
struct group *ent;
if(name[0] == '#')
***************
*** 1110,1115 ****
--- 1117,1123 ----
exit(1);
}
return(ent->gr_gid);
+ #endif
}
#if 0
1.59 +112 -7 apache/src/util_script.c
Index: util_script.c
===================================================================
RCS file: /export/home/cvs/apache/src/util_script.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -C3 -r1.58 -r1.59
*** util_script.c 1997/05/11 23:13:22 1.58
--- util_script.c 1997/06/15 19:22:34 1.59
***************
*** 421,427 ****
rputs(ss, r);
}
! #ifdef __EMX__
static char **create_argv_cmd(pool *p, char *av0, const char *args, char *path)
{
register int x,n;
--- 421,427 ----
rputs(ss, r);
}
! #if defined(__EMX__) || defined(WIN32)
static char **create_argv_cmd(pool *p, char *av0, const char *args, char *path)
{
register int x,n;
***************
*** 452,459 ****
#endif
! void call_exec (request_rec *r, char *argv0, char **env, int shellcmd)
{
#if defined(RLIMIT_CPU) || defined(RLIMIT_NPROC) || \
defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
--- 452,460 ----
#endif
! int call_exec (request_rec *r, char *argv0, char **env, int shellcmd)
{
+ int pid = 0;
#if defined(RLIMIT_CPU) || defined(RLIMIT_NPROC) || \
defined(RLIMIT_DATA) || defined(RLIMIT_VMEM)
***************
*** 506,512 ****
/* write(2, err_string, strlen(err_string)); */
/* exit(0); */
log_unixerr("fopen", NULL, err_string, r->server);
! return;
}
fgets (interpreter, 2048, program);
fclose (program);
--- 507,513 ----
/* write(2, err_string, strlen(err_string)); */
/* exit(0); */
log_unixerr("fopen", NULL, err_string, r->server);
! return(pid);
}
fgets (interpreter, 2048, program);
fclose (program);
***************
*** 561,566 ****
--- 562,670 ----
execv(r->filename,
create_argv(r->pool, NULL, NULL, NULL, argv0, r->args));
}
+ return(pid);
+ }
+ #elif defined(WIN32)
+ {
+ /* Adapted from work by Alec Kloss, to allow exec'ing of scripts under OS/2 */
+ int is_script = 0;
+ int is_binary = 0;
+ char interpreter[2048]; /* hope this is large enough for the interpreter path */
+ FILE * program;
+ int i, sz;
+ char *dot;
+ char *exename;
+ int is_exe = 0;
+
+ interpreter[0] = 0;
+
+ exename = strrchr(r->filename, '/');
+ if(!exename)
+ exename = strrchr(r->filename, '\\');
+ if(!exename)
+ exename = r->filename;
+ else
+ exename++;
+ dot = strrchr(exename, '.');
+ if(dot)
+ {
+ if(!strcasecmp(dot, ".BAT") ||
+ !strcasecmp(dot, ".EXE") ||
+ !strcasecmp(dot, ".COM"))
+ is_exe = 1;
+ }
+ if(!is_exe)
+ {
+ program = fopen (r->filename, "rb");
+ if (!program) {
+ char err_string[HUGE_STRING_LEN];
+ ap_snprintf(err_string, sizeof(err_string), "open of %s failed, errno is %d\n", r->filename, errno);
+ /* write(2, err_string, strlen(err_string)); */
+ /* exit(0); */
+ log_unixerr("fopen", NULL, err_string, r->server);
+ return(pid);
+ }
+ sz = fread (interpreter, 1, 2047, program);
+ if(sz < 0) {
+ char err_string[HUGE_STRING_LEN];
+ ap_snprintf(err_string, sizeof(err_string), "open of %s failed, errno is %d\n", r->filename, errno);
+ log_unixerr("fread", NULL, err_string, r->server);
+ fclose(program);
+ return(pid);
+ }
+ interpreter[sz] = 0;
+ fclose (program);
+ if (!strncmp (interpreter, "#!", 2)) {
+ is_script = 1;
+ for(i=2; i<2048; i++)
+ {
+ if((interpreter[i] == '\r') ||
+ (interpreter[i] == '\n'))
+ break;
+ }
+ interpreter[i] = 0;
+ } else {
+ /*
+ * check and see how many control chars. On
+ * that basis, I will classify it as a text
+ * or binary file
+ */
+ int ctrl = 0;
+
+ for(i=0; i<sz; i++)
+ {
+ static char *spec = "\r\n\t";
+ if(iscntrl(interpreter[i]) && !strchr(spec, interpreter[i]))
+ ctrl++;
+ }
+ if(ctrl > sz/10)
+ is_binary = 1;
+ else
+ is_binary = 0;
+
+ }
+ }
+
+ if ((!r->args) || (!r->args[0]) || (ind(r->args,'=') >= 0)) {
+ if (is_exe || is_binary) {
+ pid = spawnle(_P_NOWAIT, r->filename, r->filename, NULL, env);
+ } else if(is_script) {
+ pid = spawnle(_P_NOWAIT, interpreter+2, interpreter+2, r->filename, NULL, env);
+ } else {
+ pid = spawnle(_P_NOWAIT, "CMD.EXE", "CMD.EXE", "/C", r->filename, NULL, env);
+ }
+ }
+ else {
+ if (is_exe || is_binary) {
+ pid = spawnve(_P_NOWAIT, r->filename, create_argv(r->pool, argv0, NULL, NULL, r->args, (void *)NULL), env);
+ } else if(is_script) {
+ assert(0);
+ pid = spawnve(_P_NOWAIT, interpreter+2, create_argv(r->pool, interpreter+2, NULL, NULL, r->filename, r->args), env);
+ } else {
+ pid = spawnve(_P_NOWAIT, "CMD.EXE", create_argv_cmd(r->pool, argv0, r->args, r->filename), env);
+ }
+ }
+ return(pid);
}
#else
if ( suexec_enabled &&
***************
*** 581,594 ****
if ((pw = getpwnam(username)) == NULL) {
log_unixerr("getpwnam",username,"invalid username",r->server);
! return;
}
execuser = pstrcat(r->pool, "~", pw->pw_name, NULL);
user_gid = pw->pw_gid;
if ((gr = getgrgid(user_gid)) == NULL) {
if ((grpname = palloc (r->pool, 16)) == NULL)
! return;
else
ap_snprintf(grpname, 16, "%d", user_gid);
}
--- 685,698 ----
if ((pw = getpwnam(username)) == NULL) {
log_unixerr("getpwnam",username,"invalid username",r->server);
! return(pid);
}
execuser = pstrcat(r->pool, "~", pw->pw_name, NULL);
user_gid = pw->pw_gid;
if ((gr = getgrgid(user_gid)) == NULL) {
if ((grpname = palloc (r->pool, 16)) == NULL)
! return(pid);
else
ap_snprintf(grpname, 16, "%d", user_gid);
}
***************
*** 598,610 ****
else {
if ((pw = getpwuid (r->server->server_uid)) == NULL) {
log_unixerr("getpwuid", NULL, "invalid userid", r->server);
! return;
}
execuser = pstrdup(r->pool, pw->pw_name);
if ((gr = getgrgid (r->server->server_gid)) == NULL) {
log_unixerr("getgrgid", NULL, "invalid groupid", r->server);
! return;
}
grpname = gr->gr_name;
}
--- 702,714 ----
else {
if ((pw = getpwuid (r->server->server_uid)) == NULL) {
log_unixerr("getpwuid", NULL, "invalid userid", r->server);
! return(pid);
}
execuser = pstrdup(r->pool, pw->pw_name);
if ((gr = getgrgid (r->server->server_gid)) == NULL) {
log_unixerr("getgrgid", NULL, "invalid groupid", r->server);
! return(pid);
}
grpname = gr->gr_name;
}
***************
*** 634,638 ****
--- 738,743 ----
create_argv(r->pool, NULL, NULL, NULL, argv0, r->args),
env);
}
+ return(pid);
#endif
}
1.17 +1 -1 apache/src/util_script.h
Index: util_script.h
===================================================================
RCS file: /export/home/cvs/apache/src/util_script.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -C3 -r1.16 -r1.17
*** util_script.h 1997/04/29 03:41:13 1.16
--- util_script.h 1997/06/15 19:22:35 1.17
***************
*** 65,69 ****
#define scan_script_header(a1,a2) scan_script_header_err(a1,a2,NULL)
int scan_script_header_err(request_rec *r, FILE *f, char *buffer);
void send_size(size_t size, request_rec *r);
! void call_exec (request_rec *r, char *argv0, char **env, int shellcmd);
--- 65,69 ----
#define scan_script_header(a1,a2) scan_script_header_err(a1,a2,NULL)
int scan_script_header_err(request_rec *r, FILE *f, char *buffer);
void send_size(size_t size, request_rec *r);
! int call_exec (request_rec *r, char *argv0, char **env, int shellcmd);
1.13 +10 -1 apache/src/modules/proxy/mod_proxy.c
Index: mod_proxy.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/mod_proxy.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -C3 -r1.12 -r1.13
*** mod_proxy.c 1997/04/28 20:54:40 1.12
--- mod_proxy.c 1997/06/15 19:22:47 1.13
***************
*** 179,184 ****
--- 179,193 ----
else return OK; /* otherwise; we've done the best we can */
}
+ static int
+ proxy_init(server_rec *r, pool *p)
+ {
+ proxy_garbage_init(r, p);
+
+ return(0);
+ }
+
+
/* -------------------------------------------------------------- */
/* Invoke handler */
***************
*** 535,541 ****
module proxy_module = {
STANDARD_MODULE_STUFF,
! NULL, /* initializer */
NULL, /* create per-directory config structure */
NULL, /* merge per-directory config structures */
create_proxy_config, /* create per-server config structure */
--- 544,550 ----
module proxy_module = {
STANDARD_MODULE_STUFF,
! proxy_init, /* initializer */
NULL, /* create per-directory config structure */
NULL, /* merge per-directory config structures */
create_proxy_config, /* create per-server config structure */
1.12 +1 -0 apache/src/modules/proxy/mod_proxy.h
Index: mod_proxy.h
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/mod_proxy.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -C3 -r1.11 -r1.12
*** mod_proxy.h 1997/04/16 00:13:05 1.11
--- mod_proxy.h 1997/06/15 19:22:47 1.12
***************
*** 270,273 ****
--- 270,274 ----
int proxyerror(request_rec *r, const char *message);
const char *proxy_host2addr(const char *host, struct hostent *reqhp);
int proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
+ int proxy_garbage_init(server_rec *, pool *);
1.14 +53 -8 apache/src/modules/proxy/proxy_cache.c
Index: proxy_cache.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_cache.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -C3 -r1.13 -r1.14
*** proxy_cache.c 1997/05/29 15:16:01 1.13
--- proxy_cache.c 1997/06/15 19:22:47 1.14
***************
*** 58,64 ****
--- 58,70 ----
#include "http_log.h"
#include "http_main.h"
#include "util_date.h"
+ #ifdef WIN32
+ #include <sys/utime.h>
+ #include "nt/dirent.h"
+ #else
#include <utime.h>
+ #endif /* WIN32 */
+ #include "multithread.h"
#define abs(c) ((c) >= 0 ? (c) : -(c))
***************
*** 84,94 ****
--- 90,135 ----
static unsigned long int curblocks;
static time_t now, expire;
static char *filename;
+ static mutex *garbage_mutex = NULL;
+
+
+ int
+ proxy_garbage_init(server_rec *r, pool *p)
+ {
+ if(!garbage_mutex)
+ garbage_mutex = create_mutex(NULL);
+
+ return(0);
+ }
+
static int sub_garbage_coll(request_rec *r,array_header *files,
const char *cachedir,const char *cachesubdir);
+ static void help_proxy_garbage_coll(request_rec *r);
void proxy_garbage_coll(request_rec *r)
+ {
+ static int inside = 0;
+
+ acquire_mutex(garbage_mutex);
+ if(inside == 1)
+ {
+ release_mutex(garbage_mutex);
+ return;
+ }
+ else
+ inside = 1;
+ release_mutex(garbage_mutex);
+
+ help_proxy_garbage_coll(r);
+
+ acquire_mutex(garbage_mutex);
+ inside = 0;
+ release_mutex(garbage_mutex);
+ }
+
+
+ void help_proxy_garbage_coll(request_rec *r)
{
const char *cachedir;
void *sconf = r->server->module_config;
***************
*** 196,202 ****
struct stat buf;
int fd,i;
DIR *dir;
! #if defined(NEXT)
struct DIR_TYPE *ent;
#else
struct dirent *ent;
--- 237,243 ----
struct stat buf;
int fd,i;
DIR *dir;
! #if defined(NEXT) || defined(WIN32)
struct DIR_TYPE *ent;
#else
struct dirent *ent;
***************
*** 244,250 ****
/* if (strlen(ent->d_name) != HASH_LEN) continue; */
/* read the file */
! fd = open(filename, O_RDONLY);
if (fd == -1)
{
if (errno != ENOENT) proxy_log_uerror("open", filename,NULL,
--- 285,291 ----
/* if (strlen(ent->d_name) != HASH_LEN) continue; */
/* read the file */
! fd = open(filename, O_RDONLY | O_BINARY);
if (fd == -1)
{
if (errno != ENOENT) proxy_log_uerror("open", filename,NULL,
***************
*** 421,427 ****
proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
struct cache_req **cr)
{
! char hashfile[33], *imstr, *pragma, *p, *auth;
struct cache_req *c;
time_t now;
BUFF *cachefp;
--- 462,468 ----
proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
struct cache_req **cr)
{
! char hashfile[66], *imstr, *pragma, *p, *auth;
struct cache_req *c;
time_t now;
BUFF *cachefp;
***************
*** 466,476 ****
auth == NULL)
{
Explain1("Check file %s",c->filename);
! cfd = open(c->filename, O_RDWR);
if (cfd != -1)
{
note_cleanups_for_fd(r->pool, cfd);
! cachefp = bcreate(r->pool, B_RD | B_WR);
bpushfd(cachefp, cfd, cfd);
} else if (errno != ENOENT)
proxy_log_uerror("open", c->filename,
--- 507,517 ----
auth == NULL)
{
Explain1("Check file %s",c->filename);
! cfd = open(c->filename, O_RDWR | O_BINARY);
if (cfd != -1)
{
note_cleanups_for_fd(r->pool, cfd);
! cachefp = bcreate(r->pool, B_RD | B_WR, 0);
bpushfd(cachefp, cfd, cfd);
} else if (errno != ENOENT)
proxy_log_uerror("open", c->filename,
***************
*** 807,813 ****
Explain1("Create temporary file %s",c->tempfile);
! i = open(c->tempfile, O_WRONLY | O_CREAT | O_EXCL, 0622);
if (i == -1)
{
proxy_log_uerror("open", c->tempfile,
--- 848,854 ----
Explain1("Create temporary file %s",c->tempfile);
! i = open(c->tempfile, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0622);
if (i == -1)
{
proxy_log_uerror("open", c->tempfile,
***************
*** 815,821 ****
return DECLINED;
}
note_cleanups_for_fd(r->pool, i);
! c->fp = bcreate(r->pool, B_WR);
bpushfd(c->fp, -1, i);
if (bvputs(c->fp, buff, "X-URL: ", c->url, "\n", NULL) == -1)
--- 856,862 ----
return DECLINED;
}
note_cleanups_for_fd(r->pool, i);
! c->fp = bcreate(r->pool, B_WR, 0);
bpushfd(c->fp, -1, i);
if (bvputs(c->fp, buff, "X-URL: ", c->url, "\n", NULL) == -1)
***************
*** 904,916 ****
if(!p)
break;
*p='\0';
if(mkdir(c->filename,S_IREAD|S_IWRITE|S_IEXEC) < 0 && errno != EEXIST)
proxy_log_uerror("mkdir",c->filename,
"proxy: error creating cache directory",s);
*p='/';
++p;
}
! #ifdef __EMX__
/* Under OS/2 use rename. */
if (rename(c->tempfile, c->filename) == -1)
proxy_log_uerror("rename", c->filename,
--- 945,961 ----
if(!p)
break;
*p='\0';
+ #ifdef WIN32
+ if(mkdir(c->filename) < 0 && errno != EEXIST)
+ #else
if(mkdir(c->filename,S_IREAD|S_IWRITE|S_IEXEC) < 0 && errno != EEXIST)
+ #endif /* WIN32 */
proxy_log_uerror("mkdir",c->filename,
"proxy: error creating cache directory",s);
*p='/';
++p;
}
! #if defined(__EMX__) || defined(WIN32)
/* Under OS/2 use rename. */
if (rename(c->tempfile, c->filename) == -1)
proxy_log_uerror("rename", c->filename,
1.9 +1 -1 apache/src/modules/proxy/proxy_connect.c
Index: proxy_connect.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_connect.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -C3 -r1.8 -r1.9
*** proxy_connect.c 1997/04/24 23:21:35 1.8
--- proxy_connect.c 1997/06/15 19:22:48 1.9
***************
*** 221,227 ****
else break;
}
! pclosef(r->pool,sock);
return OK;
}
--- 221,227 ----
else break;
}
! pclosesocket(r->pool,sock);
return OK;
}
1.22 +25 -25 apache/src/modules/proxy/proxy_ftp.c
Index: proxy_ftp.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_ftp.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -C3 -r1.21 -r1.22
*** proxy_ftp.c 1997/04/22 03:29:37 1.21
--- proxy_ftp.c 1997/06/15 19:22:48 1.22
***************
*** 497,510 ****
r->server);
return SERVER_ERROR;
}
! note_cleanups_for_fd(pool, sock);
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&one,
sizeof(int)) == -1)
{
proxy_log_uerror("setsockopt", NULL,
"proxy: error setting reuseaddr option", r->server);
! pclosef(pool, sock);
return SERVER_ERROR;
}
--- 497,510 ----
r->server);
return SERVER_ERROR;
}
! note_cleanups_for_socket(pool, sock);
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&one,
sizeof(int)) == -1)
{
proxy_log_uerror("setsockopt", NULL,
"proxy: error setting reuseaddr option", r->server);
! pclosesocket(pool, sock);
return SERVER_ERROR;
}
***************
*** 520,526 ****
if (i == -1)
return proxyerror(r, "Could not connect to remote machine");
! f = bcreate(pool, B_RDWR);
bpushfd(f, sock, sock);
/* shouldn't we implement telnet control options here? */
--- 520,526 ----
if (i == -1)
return proxyerror(r, "Could not connect to remote machine");
! f = bcreate(pool, B_RDWR, 1);
bpushfd(f, sock, sock);
/* shouldn't we implement telnet control options here? */
***************
*** 667,677 ****
{
proxy_log_uerror("socket", NULL, "proxy: error creating PASV socket",
r->server);
! pclosef(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
}
! note_cleanups_for_fd(pool, dsock);
bputs("PASV\015\012", f);
bflush(f);
--- 667,677 ----
{
proxy_log_uerror("socket", NULL, "proxy: error creating PASV socket",
r->server);
! pclosesocket(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
}
! note_cleanups_for_socket(pool, dsock);
bputs("PASV\015\012", f);
bflush(f);
***************
*** 683,690 ****
{
proxy_log_uerror("command", NULL, "PASV: control connection is toast",
r->server);
! pclosef(pool, dsock);
! pclosef(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
} else
--- 683,690 ----
{
proxy_log_uerror("command", NULL, "PASV: control connection is toast",
r->server);
! pclosesocket(pool, dsock);
! pclosesocket(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
} else
***************
*** 721,732 ****
return proxyerror(r, "Could not connect to remote machine");
}
else {
! data = bcreate(pool, B_RDWR);
bpushfd(data, dsock, dsock);
pasvmode = 1;
}
} else
! pclosef(pool, dsock); /* and try the regular way */
}
if (!pasvmode) /* set up data connection */
--- 721,732 ----
return proxyerror(r, "Could not connect to remote machine");
}
else {
! data = bcreate(pool, B_RDWR, 1);
bpushfd(data, dsock, dsock);
pasvmode = 1;
}
} else
! pclosesocket(pool, dsock); /* and try the regular way */
}
if (!pasvmode) /* set up data connection */
***************
*** 736,742 ****
{
proxy_log_uerror("getsockname", NULL,
"proxy: error getting socket address", r->server);
! pclosef(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
}
--- 736,742 ----
{
proxy_log_uerror("getsockname", NULL,
"proxy: error getting socket address", r->server);
! pclosesocket(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
}
***************
*** 746,752 ****
{
proxy_log_uerror("socket", NULL, "proxy: error creating socket",
r->server);
! pclosef(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
}
--- 746,752 ----
{
proxy_log_uerror("socket", NULL, "proxy: error creating socket",
r->server);
! pclosesocket(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
}
***************
*** 757,764 ****
{
proxy_log_uerror("setsockopt", NULL,
"proxy: error setting reuseaddr option", r->server);
! pclosef(pool, dsock);
! pclosef(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
}
--- 757,764 ----
{
proxy_log_uerror("setsockopt", NULL,
"proxy: error setting reuseaddr option", r->server);
! pclosesocket(pool, dsock);
! pclosesocket(pool, sock);
kill_timeout(r);
return SERVER_ERROR;
}
***************
*** 771,778 ****
ap_snprintf(buff, sizeof(buff), "%s:%d", inet_ntoa(server.sin_addr), server.sin_port);
proxy_log_uerror("bind", buff,
"proxy: error binding to ftp data socket", r->server);
! pclosef(pool, sock);
! pclosef(pool, dsock);
}
listen(dsock, 2); /* only need a short queue */
}
--- 771,778 ----
ap_snprintf(buff, sizeof(buff), "%s:%d", inet_ntoa(server.sin_addr), server.sin_port);
proxy_log_uerror("bind", buff,
"proxy: error binding to ftp data socket", r->server);
! pclosesocket(pool, sock);
! pclosesocket(pool, dsock);
}
listen(dsock, 2); /* only need a short queue */
}
***************
*** 912,919 ****
if (i != DECLINED)
{
! pclosef(pool, dsock);
! pclosef(pool, sock);
return i;
}
cache = c->fp;
--- 912,919 ----
if (i != DECLINED)
{
! pclosesocket(pool, dsock);
! pclosesocket(pool, sock);
return i;
}
cache = c->fp;
***************
*** 928,941 ****
{
proxy_log_uerror("accept", NULL,
"proxy: failed to accept data connection", r->server);
! pclosef(pool, dsock);
! pclosef(pool, sock);
kill_timeout(r);
proxy_cache_error(c);
return BAD_GATEWAY;
}
! note_cleanups_for_fd(pool, csd);
! data = bcreate(pool, B_RDWR);
bpushfd(data, csd, -1);
kill_timeout(r);
}
--- 928,941 ----
{
proxy_log_uerror("accept", NULL,
"proxy: failed to accept data connection", r->server);
! pclosesocket(pool, dsock);
! pclosesocket(pool, sock);
kill_timeout(r);
proxy_cache_error(c);
return BAD_GATEWAY;
}
! note_cleanups_for_socket(pool, csd);
! data = bcreate(pool, B_RDWR, 1);
bpushfd(data, csd, -1);
kill_timeout(r);
}
***************
*** 986,992 ****
bputs("ABOR\015\012", f);
bflush(f);
if (!pasvmode)
! pclosef(pool, csd);
Explain0("FTP: ABOR");
/* responses: 225, 226, 421, 500, 501, 502 */
i = ftp_getrc(f);
--- 986,992 ----
bputs("ABOR\015\012", f);
bflush(f);
if (!pasvmode)
! pclosesocket(pool, csd);
Explain0("FTP: ABOR");
/* responses: 225, 226, 421, 500, 501, 502 */
i = ftp_getrc(f);
***************
*** 1003,1011 ****
/* responses: 221, 500 */
if (!pasvmode)
! pclosef(pool, csd);
! pclosef(pool, dsock);
! pclosef(pool, sock);
proxy_garbage_coll(r);
--- 1003,1011 ----
/* responses: 221, 500 */
if (!pasvmode)
! pclosesocket(pool, csd);
! pclosesocket(pool, dsock);
! pclosesocket(pool, sock);
proxy_garbage_coll(r);
1.18 +6 -6 apache/src/modules/proxy/proxy_http.c
Index: proxy_http.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_http.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -C3 -r1.17 -r1.18
*** proxy_http.c 1997/04/11 05:10:51 1.17
--- proxy_http.c 1997/06/15 19:22:48 1.18
***************
*** 224,230 ****
log_error("proxy: error creating socket", r->server);
return SERVER_ERROR;
}
! note_cleanups_for_fd(pool, sock);
j = 0;
--- 224,230 ----
log_error("proxy: error creating socket", r->server);
return SERVER_ERROR;
}
! note_cleanups_for_socket(pool, sock);
j = 0;
***************
*** 244,250 ****
clear_connection(r->headers_in); /* Strip connection-based headers */
! f = bcreate(pool, B_RDWR);
bpushfd(f, sock, sock);
hard_timeout ("proxy send", r);
--- 244,250 ----
clear_connection(r->headers_in); /* Strip connection-based headers */
! f = bcreate(pool, B_RDWR, 1);
bpushfd(f, sock, sock);
hard_timeout ("proxy send", r);
***************
*** 281,287 ****
len = bgets(buffer, HUGE_STRING_LEN-1, f);
if (len == -1 || len == 0)
{
! pclosef(pool, sock);
kill_timeout(r);
return proxyerror(r, "Error reading from remote server");
}
--- 281,287 ----
len = bgets(buffer, HUGE_STRING_LEN-1, f);
if (len == -1 || len == 0)
{
! pclosesocket(pool, sock);
kill_timeout(r);
return proxyerror(r, "Error reading from remote server");
}
***************
*** 292,298 ****
/* If not an HTTP/1 messsage or if the status line was > 8192 bytes */
if (buffer[5] != '1' || buffer[len-1] != '\n')
{
! pclosef(pool, sock);
kill_timeout(r);
return BAD_GATEWAY;
}
--- 292,298 ----
/* If not an HTTP/1 messsage or if the status line was > 8192 bytes */
if (buffer[5] != '1' || buffer[len-1] != '\n')
{
! pclosesocket(pool, sock);
kill_timeout(r);
return BAD_GATEWAY;
}
***************
*** 354,360 ****
i = proxy_cache_update(c, resp_hdrs, inprotocol, nocache);
if (i != DECLINED)
{
! pclosef(pool, sock);
return i;
}
--- 354,360 ----
i = proxy_cache_update(c, resp_hdrs, inprotocol, nocache);
if (i != DECLINED)
{
! pclosesocket(pool, sock);
return i;
}
***************
*** 406,412 ****
proxy_cache_tidy(c);
! pclosef(pool, sock);
proxy_garbage_coll(r);
return OK;
--- 406,412 ----
proxy_cache_tidy(c);
! pclosesocket(pool, sock);
proxy_garbage_coll(r);
return OK;
1.18 +77 -5 apache/src/modules/proxy/proxy_util.c
Index: proxy_util.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_util.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -C3 -r1.17 -r1.18
*** proxy_util.c 1997/06/04 21:20:27 1.17
--- proxy_util.c 1997/06/15 19:22:49 1.18
***************
*** 55,60 ****
--- 55,61 ----
#include "mod_proxy.h"
#include "http_main.h"
#include "md5.h"
+ #include "multithread.h"
/* already called in the knowledge that the characters are hex digits */
int
***************
*** 235,242 ****
--- 236,249 ----
if (!isdigit(host[i]) && host[i] != '.')
break;
/* must be an IP address */
+ #ifdef WIN32
+ if (host[i] == '\0' && (inet_addr(host) == -1))
+ #else
if (host[i] == '\0' && (inet_addr(host) == -1 || inet_network(host) == -1))
+ #endif
+ {
return "Bad IP address in URL";
+ }
*urlp = url;
*hostp = host;
***************
*** 419,424 ****
--- 426,433 ----
if (f2 != NULL) {
pclosef(c->req->pool, c->fp->fd);
c->fp = NULL;
+ f2 = NULL;
+ con->aborted = 1;
unlink(c->tempfile);
}
break;
***************
*** 549,554 ****
--- 558,619 ----
return 0;
}
+ #ifdef WIN32
+
+ /*
+ * On NT, the file system is NOT case sensitive. So, a == A
+ * need to map to smaller set of characters
+ */
+ void
+ proxy_hash(const char *it, char *val,int ndepth,int nlength)
+ {
+ MD5_CTX context;
+ unsigned char digest[16];
+ char tmp[26];
+ int i, k, d;
+ unsigned int x;
+ static const char table[32]= "abcdefghijklmnopqrstuvwxyz012345";
+
+ MD5Init(&context);
+ MD5Update(&context, (const unsigned char *)it, strlen(it));
+ MD5Final(digest, &context);
+
+ /* encode 128 bits as 26 characters, using a modified uuencoding */
+ /* the encoding is 5 bytes -> 8 characters
+ * i.e. 128 bits is 3 x 5 bytes + 1 byte -> 3 * 8 characters + 2 characters
+ */
+ for (i=0, k=0; i < 15; i += 5)
+ {
+ x = (digest[i] << 24) | (digest[i+1] << 16) | (digest[i+2] << 8) | digest[i+3];
+ tmp[k++] = table[x >> 27];
+ tmp[k++] = table[(x >> 22) & 0x1f];
+ tmp[k++] = table[(x >> 17) & 0x1f];
+ tmp[k++] = table[(x >> 12) & 0x1f];
+ tmp[k++] = table[(x >> 7) & 0x1f];
+ tmp[k++] = table[(x >> 2) & 0x1f];
+ x = ((x & 0x3) << 8) | digest[i+4];
+ tmp[k++] = table[x >> 5];
+ tmp[k++] = table[x & 0x1f];
+ }
+ /* one byte left */
+ x = digest[15];
+ tmp[k++] = table[x >> 3]; /* use up 5 bits */
+ tmp[k++] = table[x & 0x7];
+ /* now split into directory levels */
+
+ for(i=k=d=0 ; d < ndepth ; ++d)
+ {
+ strncpy(&val[i],&tmp[k],nlength);
+ k+=nlength;
+ val[i+nlength]='/';
+ i+=nlength+1;
+ }
+ memcpy(&val[i],&tmp[k],22-k);
+ val[i+22-k]='\0';
+ }
+
+ #else
+
void
proxy_hash(const char *it, char *val,int ndepth,int nlength)
{
***************
*** 593,598 ****
--- 658,665 ----
val[i+22-k]='\0';
}
+ #endif /* WIN32 */
+
/*
* Converts 8 hex digits to a time integer
*/
***************
*** 699,707 ****
{
int i;
struct hostent *hp;
! static struct hostent hpbuf;
! static u_long ipaddr;
! static char* charpbuf[2];
for (i=0; host[i] != '\0'; i++)
if (!isdigit(host[i]) && host[i] != '.')
--- 766,774 ----
{
int i;
struct hostent *hp;
! static __declspec( thread ) struct hostent hpbuf;
! static __declspec( thread ) u_long ipaddr;
! static __declspec( thread ) char* charpbuf[2];
for (i=0; host[i] != '\0'; i++)
if (!isdigit(host[i]) && host[i] != '.')
***************
*** 737,744 ****
int i;
hard_timeout("proxy connect", r);
! do i = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
! while (i == -1 && errno == EINTR);
if (i == -1) proxy_log_uerror("connect", NULL, NULL, r->server);
kill_timeout(r);
--- 804,816 ----
int i;
hard_timeout("proxy connect", r);
! do {
! i = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
! #ifdef WIN32
! if(i == SOCKET_ERROR)
! errno = WSAGetLastError() - WSABASEERR;
! #endif /* WIN32 */
! } while (i == -1 && errno == EINTR);
if (i == -1) proxy_log_uerror("connect", NULL, NULL, r->server);
kill_timeout(r);