Commit 53bf56f8 authored by Fred Drake's avatar Fred Drake

The pcgi/ directory will no longer be distributed with Zope 2.7. The files

it contains have been moved to the Packages/pcgi module in the cvs.zope.org
public CVS repository; it can be distributed as a separate package for those
who need it.
parent 0f6a4160
#!/usr/local/bin/pcgi-wrapper
# example pcgi info file - JeffBauer@bigfoot.com
# substitute 'BogusDirectory' with appropriate path
# and subsitute the correct path to your Python binary
# for PCGI_EXE.
#
# To invoke from browser: http://.../cgi-bin/pcgitest/getTime
PCGI_EXE=/usr/local/bin/python
PCGI_PUBLISHER=/BogusDirectory/pcgi_publisher.py
PCGI_MODULE_PATH=/BogusDirectory/pcgitime.py
PCGI_SOCKET_FILE=/tmp/pcgitest.socket
PCGI_PID_FILE=/tmp/pcgitest.pid
# pcgitime.py - example pcgi script - JeffBauer@bigfoot.com
from time import asctime, localtime, time
beginTime = "<html><pre>time started: %s" % asctime(localtime(time()))
def getTime(arg=None):
"""It's later than you think (don't remove this docstring)"""
return "%s\ncurrent time: %s" % (beginTime, asctime(localtime(time())))
### Makefile.in - Persistent CGI configuration ###
### start of system configuration section ###
prefix= @prefix@
exec_prefix= @exec_prefix@
BINDIR= $(exec_prefix)/bin
srcdir= @srcdir@
VPATH = @srcdir@
VERSION= @VERSION@
MACHDEP= @MACHDEP@
CC = @CC@
CFLAGS= @CFLAGS@
DEFS= @DEFS@ -DUNIX -DOPT_NO_STDERR -DCLOSE_FDS
LIBS= @LIBS@
creosotedir = $(srcdir)/MrCreosote
testdir = $(srcdir)/Test
utildir = $(srcdir)/Util
### end of system configuration section ###
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) $(CFLAGS) $<
PROGS = pcgi-wrapper $(creosotedir)/pcgi-creosote $(testdir)/parseinfo
SRCS = pcgi-wrapper.c parseinfo.c $(creosotedir)/creosote.c
OBJS1 = pcgi-wrapper.o parseinfo.o
OBJS2 = $(creosotedir)/pcgi-wrapper.o parseinfo.o $(creosotedir)/creosote.o
OBJS3 = $(srcdir)/pcgi-wrapper.o $(testdir)/parseinfo.o
HDRS = pcgi.h $(creosotedir)/creosote.h
# --with-XXX options for configure
WITH=
MANIFEST=$(srcdir)/manifest
# default path permission settings
DIRMODE= 775
EXEMODE= 755
FILEMODE= 644
# Portable install script (configure doesn't always guess right)
INSTALL= ./install-sh -c
INSTALL_PROGRAM=${INSTALL} -m $(EXEMODE)
INSTALL_DATA= ${INSTALL} -m $(FILEMODE)
##################################################
all: pcgi-wrapper $(testdir)/parseinfo
pcgi-wrapper.o: pcgi-wrapper.c pcgi.h
$(CC) -c -I. -I$(srcdir) $(CFLAGS) -DPCGI_WRAPPER_MAIN -DVERSION=\"$(VERSION)\" $(DEFS) $(srcdir)/pcgi-wrapper.c
parseinfo.o: parseinfo.c pcgi.h
$(CC) -c -I. -I$(srcdir) $(CFLAGS) $(DEFS) $(srcdir)/parseinfo.c
pcgi-wrapper: pcgi-wrapper.o parseinfo.o
$(CC) $(LIBS) $(LDFLAGS) -o pcgi-wrapper $(OBJS1)
### begin CREOSOTE stuff ###
$(creosotedir)/creosote.o: $(creosotedir)/creosote.c $(creosotedir)/creosote.h
$(CC) -c -o $(creosotedir)/creosote.o -I. -I$(srcdir) -I$(creosotedir) $(CFLAGS) -DCREOSOTE $(DEFS) $(creosotedir)/creosote.c
$(creosotedir)/pcgi-wrapper.o: $(srcdir)/pcgi-wrapper.c
$(CC) -c -o $(creosotedir)/pcgi-wrapper.o -I. -I$(srcdir) -I$(creosotedir) $(CFLAGS) -DPCGI_WRAPPER_MAIN -DCREOSOTE $(DEFS) $(srcdir)/pcgi-wrapper.c
creosote: $(creosotedir)/pcgi-creosote
$(creosotedir)/pcgi-creosote: $(creosotedir)/pcgi-wrapper.o parseinfo.o $(creosotedir)/creosote.o
$(CC) $(LIBS) $(LDFLAGS) -o $(creosotedir)/pcgi-creosote $(OBJS2)
### end CREOSOTE stuff ###
### begin TEST stuff ###
$(testdir)/parseinfo.o: $(srcdir)/parseinfo.c
$(CC) -c -o $(testdir)/parseinfo.o -I. -I$(srcdir) -I$(testdir) $(CFLAGS) -DMAIN_PARSEINFO $(DEFS) $(srcdir)/parseinfo.c
$(testdir)/pcgi-wrapper.o: $(srcdir)/pcgi-wrapper.c
$(CC) -c -o $(testdir)/pcgi-wrapper.o -I. -I$(srcdir) -I$(testdir) $(CFLAGS) $(DEFS) $(srcdir)/pcgi-wrapper.c
parseinfo: $(testdir)/parseinfo
$(testdir)/parseinfo: $(testdir)/parseinfo.o $(testdir)/pcgi-wrapper.o
$(CC) $(LIBS) $(LDFLAGS) -o $(testdir)/parseinfo $(testdir)/parseinfo.o $(testdir)/pcgi-wrapper.o
### end TEST stuff ###
install: bininstall
bininstall: altbininstall
cp pcgi-wrapper $(BINDIR)
chmod a+rx $(BINDIR)/pcgi-wrapper
-if test -f $(BINDIR)/pcgi-wrapper; \
then rm -f $(BINDIR)/pcgi-wrapper; \
else true; \
fi
(cd $(BINDIR); ln pcgi-wrapper$(VERSION) pcgi-wrapper)
altbininstall: pcgi-wrapper
@for i in $(BINDIR); \
do \
if test ! -d $$i; then \
echo "Creating directory $$i"; \
mkdir $$i; \
chmod $(DIRMODE) $$i; \
else true; \
fi; \
done
$(INSTALL_PROGRAM) pcgi-wrapper $(BINDIR)/pcgi-wrapper$(VERSION)
clean:
rm -f $(PROGS) *.o *.out core $(creosotedir)/*.o $(testdir)/*.o $(utildir)/*.o Win32/*.obj
distclean: clean
rm -f Makefile autoconf.h config.status config.cache config.log *~
tarball:
cd $(srcdir); mkdir pcgi-$(VERSION)
cpio -pd < $(MANIFEST) pcgi-$(VERSION)
tar -czf $(srcdir)/pcgi-$(VERSION).tgz pcgi-$(VERSION)
rm -rf pcgi-$(VERSION)
# Build the toplevel Makefile
#Makefile: Makefile.in config.status
# CONFIG_FILES=Makefile $(SHELL) config.status
# Run the configure script, calling it with --recheck if config.status exists
#config.status: $(srcdir)/configure
# if test -f config.status; \
# then $(SHELL) config.status --recheck; \
# $(SHELL) config.status; \
# else $(SHELL) $(srcdir)/configure $(WITH); \
# fi
# Rebuild the configure script from configure.in
autoconf:
(cd $(srcdir); autoconf)
(cd $(srcdir); autoheader)
README.MrCreosote - JeffBauer@bigfoot.com - May 21, 1998
MrCreosote is a lightweight message-passing idiom I use
to debug multi-processor/multi-user code sometimes.i
It's basically just a matter of tossing out datagrams
(connectionless sockets). I'll document it later, in
case anyone finds it useful for debugging. For now,
just ignore the contents of this directory.
/* creosote.c */
#include "creosote.h"
struct MrCreosote CreosoteServer;
void closeMrCreosote()
{
struct MrCreosote *c = &CreosoteServer;
if (c->socket)
{
#ifdef UNIX
close(c->socket);
#endif
#ifdef WIN32
closesocket(c->socket);
WSACleanup();
#endif
}
c->socket = 0;
}
#ifdef UNIX
int initializeMrCreosote()
{
struct MrCreosote *c = &CreosoteServer;
SOCKADDR_IN addr, *serv;
creosote_socket *s;
serv = &(c->serv_addr);
s = &(c->socket);
c->port = CREOSOTE_PORT;
strcpy(c->host, CREOSOTE_HOST);
bzero(serv, sizeof(*serv));
serv->sin_family = AF_INET;
serv->sin_addr.s_addr = inet_addr(c->host);
serv->sin_port = htons(c->port);
if ((*s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
return(-1);
}
bzero((char *) &addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(0);
if (bind(*s, (struct sockaddr *) &addr, sizeof(addr)) < 0)
{
return(-1);
}
return(0);
}
#endif
#ifdef WIN32
int initializeMrCreosote()
{
struct MrCreosote *c = &CreosoteServer;
SOCKADDR_IN *serv;
creosote_socket *s;
WSADATA WsaData;
int enable = 1;
s = &(c->socket);
if (!c->port)
{
c->port = CREOSOTE_PORT;
}
if (!c->host[0])
{
strcpy(c->host, CREOSOTE_HOST);
}
if (0 != WSAStartup(MAKEWORD(2,0), &WsaData))
{
return(-1);
}
/* Set the address */
serv = &(c->serv_addr);
serv->sin_family = AF_INET;
serv->sin_addr.s_addr = inet_addr(c->host);
serv->sin_port = htons((short)c->port);
/* Create socket */
*s = socket(AF_INET, SOCK_DGRAM, 0);
if (INVALID_SOCKET == *s) { return(-1); }
/* Permit the socket to broadcast */
if (SOCKET_ERROR == setsockopt(*s, SOL_SOCKET, SO_BROADCAST, (char *) &enable, sizeof(enable)))
{
return(-1);
}
return(0);
}
#endif
void setMrCreosoteHost(char *host)
{
/*
If not using localhost, setMrCreosoteHost() must be called
before initializeMrCreosote().
*/
strcpy(CreosoteServer.host, host);
}
void setMrCreosotePort(int port)
{
/* must be done before initializeMrCreosote() is called */
CreosoteServer.port = port;
}
void spewMrCreosote(char *msg)
{
struct MrCreosote *c = &CreosoteServer;
sendto(c->socket, msg, strlen(msg), 0, (struct sockaddr *) &(c->serv_addr), sizeof(c->serv_addr));
}
#if 0
int main(int argc, char *argv[])
{
if ( (initializeMrCreosote()) < 0)
{
printf("initializeMrCreosote() failed\n");
exit(1);
}
spew("Hello, world");
closeMrCreosote();
return(0);
}
#endif
/* creosote.h */
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#define CREOSOTE_HOST "127.0.0.1"
#define CREOSOTE_PORT 7739
#define spew(x) spewMrCreosote(x)
#ifdef UNIX
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef int creosote_socket;
typedef struct sockaddr_in SOCKADDR_IN;
#endif
#ifdef WIN32
#include <windows.h>
#include <iostream.h>
#include <winsock.h>
typedef SOCKET creosote_socket;
#endif
struct MrCreosote
{
char host[256];
int port;
creosote_socket socket;
SOCKADDR_IN serv_addr;
};
/* Declarations */
void closeMrCreosote();
int initializeMrCreosote();
void spewMrCreosote(char *msg);
#!/usr/bin/env python
# creosote.py - lightweight message passing with datagrams
# JeffBauer@bigfoot.com
import sys, socket
BUFSIZE = 1024
PORT = 7739
def spew(msg, host='localhost', port=PORT):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 0))
s.sendto(msg, (host, port))
def bucket(port=PORT, logfile=None):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', port))
print 'creosote bucket waiting on port: %s' % port
if logfile:
f = open(logfile, 'a+')
while 1:
data, addr = s.recvfrom(BUFSIZE)
print `data`[1:-1]
if logfile:
f.write(`data`[1:-1]+'\n')
f.flush()
class MrCreosote:
"""lightweight message passing with datagrams"""
def __init__(self, host='localhost', port=PORT):
self.host = host
self.port = port
self.client = None
self.disabled = 0
self.redirect_server = None
self.redirect_client = None
def bucket(self, logfile=None):
bucket(self.port, logfile)
def redirector(self, host, port=PORT):
if self.disabled:
return
if self.redirect_server == None:
self.redirect_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.redirect_server.bind(('', self.port))
if self.redirect_client == None:
self.redirect_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.redirect_client.bind(('', 0))
while 1:
data, addr = self.redirect_server.recvfrom(BUFSIZE)
self.redirect_client.sendto(data, (host, port))
def spew(self, msg):
if self.disabled:
return
if self.client == None:
self.client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.client.bind(('', 0))
self.client.sendto(msg, (self.host, self.port))
if __name__ == '__main__':
"""usage: creosote [message]"""
if len(sys.argv) < 2:
bucket()
else:
from string import joinfields
spew(joinfields(sys.argv[1:],' '))
README notes for Persistent CGI - version 2.0 alpha 4
What it is?
Persistent CGI is an architecture designed by Zope Corporation
http://www.zope.com to publish web objects as long-running
processes. The pcgi component is an integral part of ZC's
Zope product, but is also provided to web developers
under open software terms. Please review the copyright appearing
in the source code for full details.
How to build?
Unix:
./configure
make
make install <-- only copies the binary, not the .py modules
Win32:
cd Win32
nmake /f Makefile.nt
A Win32 binary (pcgi-wrapper.exe) is included with the source
distribution.
How to use?
See the HOWTO section in notes I have published:
http://starship.skyport.net/crew/jbauer/persistcgi/
How to get help?
Subscribe to the Zope mailing list: zope@zope.org
Contact me: jeffbauer@bigfoot.com
Have fun.
-Jeff
README.parseinfo - JeffBauer@bigfoot.com - May 21, 1998
parseinfo is an executable to test the parsing the pcgi
info file. Although pcgifile.py can be used to test
how the pcgi-wrapper is expected to react "in vitro"
(i.e. as a CGI process) the parseinfo program actually
runs the info file through the parser code (although
it performs no further environment testing).
usage: parseinfo <pcgi-info-file>
sample output:
r->sw_info /export/home/jbauer/tmp/pcgiinfo
r->sw_name
r->sw_home
r->sw_exe /usr/local/bin/python
r->procpath /export/home/jbauer/var/pcgitime.pid
r->sockpath /export/home/jbauer/var/pcgitime.socket
r->modpath /export/home/jbauer/www/cgi-bin/pcgitime.py
r->pubpath /export/home/jbauer/www/cgi-bin/pcgi_publisher.py
r->procid 0
r->insertPath
r->pythonPath .:/usr/local/lib/python1.5:/var/share/s0/python
CloseFileDescriptors 0
pcgifile.py - JeffBauer@bigfoot.com - May 21, 1998
The pcgifile.py is a sanity tester for pcgi info files and
can be run as a stand-alone program or a CGI script. For
more information, refer to:
http://starship.skyport.net/crew/jbauer/persistcgi/pcgifile/
#!/usr/bin/env python
# killpcgi.py - kill a running pcgi process
# Copyright(c) 1998, Jeff Bauer, All rights reserved.
# killpcgi is a convenience script to kill a running
# pcgi process, provided that it is running on a
# Unix system. You pass it the path of the pcgi info
# file, and killpcgi will kill the running process and
# remove the socket/pid files.
#
# killpcgi has been built at the request of several users,
# but you may want to first examine the script and modify it
# to suit your environment.
#
# Bugs: skimpy error handling
# 0.3a minor win32 exception caught
# 0.2a Added support for NT - 8/8/98
# 0.1a Initial version
__version__ = "0.3a"
def win32_kill(pid):
"""posix-style kill command for the Win32 environment"""
import win32api, pywintypes
try:
handle = win32api.OpenProcess(1, 0, pid)
except pywintypes.error:
return -1
return (0 != win32api.TerminateProcess(handle, 0))
def killpcgi(pcgiInfoFile):
import os, sys, string
delimiter = '='
pidFile = None
socketFile = None
infoFile = open(pcgiInfoFile, 'r')
for i in infoFile.readlines():
if delimiter in i:
n,v = string.split(string.strip(i), delimiter)
if n == 'PCGI_PID_FILE':
pidFile = v
elif n == 'PCGI_SOCKET_FILE':
socketFile = v
infoFile.close()
if pidFile is None:
print "unknown pid file"
else:
f = open(pidFile)
pid = int(f.read())
f.close()
if os.name == 'nt':
if not win32_kill(pid):
print "process %d killed" % pid
elif os.name == 'posix':
if os.kill(pid, 0):
print "process %d doesn't appear to be running" % pid
else:
# safety measure (exclude it if you're fearless)
if os.system('/bin/ps -p %d | grep python > /dev/null' % pid):
print "process %d doesn't appear to be python" % pid
else:
os.kill(pid, 15)
print "process %d killed" % pid
# conservative approach: don't remove pid/socket files
# unless we're reasonably certain we have killed the
# running process
os.unlink(pidFile)
if socketFile is not None:
os.unlink(socketFile)
else:
print "kill not supported for platform:", os.name
if __name__ == '__main__':
import sys
usage = "usage: killpcgi pcgi-info-file"
if len(sys.argv) < 2:
print usage
else:
killpcgi(sys.argv[1])
This diff is collapsed.
# Makefile.nt
VERSION = 2.0a4
CC = cl
CFLAGS = /W3 /DWIN32 /I..
LIBS = wsock32.lib
SRCDIR= ..
CREOSOTE_DIR = $(SRCDIR)/MrCreosote
CORE = $(SRCDIR)/pcgi.h #parseinfo.c
.c.obj:
$(CC) /c $(CFLAGS) $*.c
all: pcgi-wrapper.exe parseinfo.exe creosote.obj
creosote.obj: $(CREOSOTE_DIR)/creosote.c $(CREOSOTE_DIR)/creosote.h
$(CC) /c $(CFLAGS) /I$(CREOSOTE_DIR) /Focreosote.obj $(CREOSOTE_DIR)/creosote.c
parseinfo1.obj: $(SRCDIR)/parseinfo.c $(CORE)
$(CC) /c $(CFLAGS) /DMAIN_PARSEINFO /Foparseinfo1.obj $(SRCDIR)/parseinfo.c
parseinfo2.obj: $(SRCDIR)/parseinfo.c $(CORE)
$(CC) /c $(CFLAGS) $(SRCDIR)/parseinfo.c /Foparseinfo2.obj
pcgi-wrapper1.obj: $(SRCDIR)/pcgi-wrapper.c $(CORE)
$(CC) /c $(CFLAGS) /I$(CREOSOTE_DIR) /DPCGI_WRAPPER_MAIN /DCREOSOTE /DVERSION=\"$(VERSION)\" /Fopcgi-wrapper1.obj $(SRCDIR)/pcgi-wrapper.c
pcgi-wrapper2.obj: $(SRCDIR)/pcgi-wrapper.c $(CORE)
$(CC) /c $(CFLAGS) /I$(CREOSOTE_DIR) /DCREOSOTE /Fopcgi-wrapper2.obj $(SRCDIR)/pcgi-wrapper.c
parseinfo.exe: parseinfo1.obj pcgi-wrapper2.obj creosote.obj
link /OUT:parseinfo.exe parseinfo1.obj pcgi-wrapper2.obj creosote.obj $(LIBS)
pcgi-wrapper.exe: pcgi-wrapper1.obj parseinfo2.obj creosote.obj
link /OUT:pcgi-wrapper.exe pcgi-wrapper1.obj parseinfo2.obj creosote.obj $(LIBS)
README.NT - one day this will grow up and become a real README file.
PCGI 2.0a4 Win32 binary release (alpha 4) August 10, 1998
contact: jeffbauer@bigfoot.com
What is this?
The collection of files below is the first Win32
release of PCGI, the Persistent CGI wrapper for
Bobo applications. For more information about Bobo,
go to Digital Creations site: http://www.digicool.com
Files (in relative order of importance):
pcgi-wrapper.exe - the main program
pcgi_publisher.py - modified to handle both Unix & Win32
pcgifile.py - indispensible for tracking down problems
pcgitime.py - sample module
pcgitest - sample PCGI info file
killpcgi.py - handy for killing the running process
parseinfo.exe - used only when necessary (to view the pcgi
info file the way pcgi-wrapper sees it)
For information about Persistent CGI, check out:
http://starship.skyport.net/crew/jbauer/persistcgi/
(This information may soon move over to www.digicool.com)
Platforms tested?
Apache/Win32 1.3.1 running on NT 4.0. However, it should
run on any Win32 platform running a server supporting http.
Basic checklist to get the sample application up and running:
0. Install Python, Bobo, and a web server on your machine.
If you haven't got these things already working, please
see my notes on the subject:
http://starship.skyport.net/crew/jbauer/apachenotes/
1. Put pcgi-wrapper.exe where you normally place your
binary executables, or in cgi-bin.
2. Put pcgi_publisher.py in a directory where you normally
put your .py scripts -- cgi-bin is okay, but you will
specify the path in your info file, regardless.
3. Put pcgitest & pcgitime.py in cgi-bin. You will have
to modify the first #! she-bang line in pcgitest to
match the path of where you put pcgi-wrapper.exe. Also,
all directives must match your environment -- the examples
included are for illustration purposes only. Please
read the online (URL above) PCGI documentation for
further information.
4. Run your setup against pcgifile.py, a sanity check
described in:
http://starship.skyport.net/crew/jbauer/persistcgi/pcgifile/
http://starship.skyport.net/crew/jbauer/persistcgi/howto
5. Give me feedback, please: jeffbauer@bigfoot.com
-------------------
Microsoft IIS Notes:
Amos Latteier notes that some web servers, notably Microsoft's IIS,
cannot deal with the first line in a CGI program like Apache:
#!C:\WINNT\system32\pcgi-wrapper.exe
The solution is to use a .pcgi extension for your info file and create
a file association between .pcgi and pcgi-wrapper.exe with an IIS script
map registry entry, e.g.:
.pcgi C:\winnt\system32\pcgi-wrapper.exe %s
Now info files with the .pcgi extension will execute as cgi
programs.
[Amos further notes in a posting to the Bobo list:]
IIS 4 by default sends a custom 404 error message which masks
Bobo's 404 error information. This effectively keeps you from
seeing what Bobo is trying to tell you about why it is not
publishing your object. To get rid of this annoyance go to
the web site properties dialog in the Microsoft Management
Console application. Click on the "Custom Errors" tab. Choose
the 404 error and change it to use "Default" error message.
Voila, you're back in business, and can read Bobo information in
the source of your 404 error messages now.
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define to empty if the keyword does not work. */
#undef const
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to `int' if <sys/types.h> doesn't define. */
#undef pid_t
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if you have the putenv function. */
#undef HAVE_PUTENV
/* Define if you have the socket function. */
#undef HAVE_SOCKET
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
This diff is collapsed.
dnl Process this file with autoconf to produce a configure script.
AC_INIT(pcgi.h)
AC_PROG_CC
AC_PROG_CPP
# Set VERSION here so we only need to edit it in one place
AC_SUBST(VERSION)
VERSION=2.0a5
# Set name for machine-dependent library files
AC_SUBST(MACHDEP)
AC_MSG_CHECKING(MACHDEP)
if test -z "$MACHDEP"
then
ac_sys_system=`uname -s`
if test "$ac_sys_system" = "AIX" ; then
ac_sys_release=`uname -v`
else
ac_sys_release=`uname -r`
fi
ac_md_system=`echo $ac_sys_system | tr -d '[/ ]' | tr '[[A-Z]]' '[[a-z]]'`
ac_md_release=`echo $ac_sys_release | tr -d '[/ ]' | sed 's/\..*//'`
MACHDEP="$ac_md_system$ac_md_release"
case $MACHDEP in
'') MACHDEP="unknown";;
esac
fi
AC_MSG_RESULT($MACHDEP)
dnl Checks for programs.
dnl Checks for libraries.
case $ac_sys_system in
hp*|HP*)
case $CC in
cc|*/cc) CC="$CC -Aa -D_HPUX_SOURCE";;
esac;;
esac
if test "$ac_sys_system" != IRIX
then
AC_CHECK_LIB(nsl, inet_addr, [LIBS="-lnsl $LIBS"]) # SVR4
AC_CHECK_LIB(socket, socket, [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets
fi
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(unistd.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
dnl Checks for library functions.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(putenv socket strerror)
AC_MSG_CHECKING(for union semun)
AC_TRY_LINK([#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>],
[union semun semun;],
AC_DEFINE(HAVE_UNION_SEMUN) AC_MSG_RESULT(yes),AC_MSG_RESULT(no))
AC_OUTPUT(Makefile)
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5; it is not part of GNU.
#
# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
instcmd="$mvprog"
chmodcmd=""
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
fi
# Make a temp file name in the proper directory.
dstdir=`dirname $dst`
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp
# and set any options; do chmod last to preserve setuid bits
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
# Now rename the file to the real destination.
$doit $rmcmd $dst
$doit $mvcmd $dsttmp $dst
exit 0
Example/pcgitest
Example/pcgitime.py
Makefile.in
MrCreosote/README.MrCreosote
MrCreosote/creosote.c
MrCreosote/creosote.h
MrCreosote/creosote.py
README
Test/README.parseinfo
Util/README
Util/killpcgi.py
Util/pcgifile.py
Win32/Makefile.nt
Win32/README.NT
Win32/parseinfo.exe
Win32/pcgi-wrapper.exe
config.h.in
configure
configure.in
install-sh
manifest
parseinfo.c
pcgi_publisher.py
pcgi-wrapper.c
pcgi.h
This diff is collapsed.
This diff is collapsed.
/* pcgi.h - Persistent CGI header file for pcgi-wrapper.c, parseinfo.c
Copyright (c) 1998, Digital Creations, Fredericksburg, VA, USA. All
rights reserved. This software includes contributions from Jeff Bauer.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
o Redistributions of source code must retain the above copyright
notice, this list of conditions, and the disclaimer that follows.
o Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
o All advertising materials mentioning features or use of this
software must display the following acknowledgement:
This product includes software developed by Digital Creations
and its contributors.
o Neither the name of Digital Creations nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS *AS IS* AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PCGI_H
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef UNIX
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#ifdef WIN32
#include <windows.h>
#include <io.h>
#include <iostream.h>
#include <winsock.h>
#include <fcntl.h>
#endif
#define MAXLINEBUFFER 12
#define PATHSEP_UNIX '/'
#define PATHSEP_WIN32 '\\'
#define DEFAULT_SOCK_PORT 7244
/*#define DEFAULT_SOCK_HOST "127.0.0.1"*/
#define MAXPATH 1024
#define PUBLISHER_NAME_1 "pcgi_publisher.py"
#define PUBLISHER_NAME_2 "pcgi_publisher.pyc"
#define PUBLISHER_NAME_3 "pcgi_publisher.pyo"
#define PUBLISHER_NAME_4 "pcgi_publisher"
#define HDRLEN 10
#define HDRFMT "%010ld"
#ifdef UNIX
#define PATHSEP PATHSEP_UNIX
typedef int pcgi_socket;
#endif
#ifdef WIN32
#define PATHSEP PATHSEP_WIN32
typedef SOCKET pcgi_socket;
#define sleep(x) Sleep(x * 1000)
#define read(x,y,z) _read(x,y,z)
#define write(x,y,z) _write(x,y,z)
#define MUTEX_NAME "pcgiMutex"
#define AUTODELAY 5
#define CONNRETRY 0
#define CONNDELAY 1
#endif
#ifndef CREOSOTE
/* no-op in case someone forgets to remove a spew() in their debug code */
#define spew(x)
#endif
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif
#define MAXSZ 256
#define RKEY 99
#define E_500 "500 Server Error"
#define E_503 "503 Service Unavailable"
#define ERR101_FAILURE_DURING_START "(101) failure during start"
#define ERR102_FAILURE_DURING_CONNECT "(102) failure during connect"
#define ERR103_UNABLE_VERIFY_RUNNING "(103) unable to verify if process is running"
#define ERR104_ENVIRONMENT_SEND "(104) environment send"
#define ERR105_STDIN_SEND "(105) stdin send"
#define ERR106_STDOUT_READ_HEADER "(106) stdout read header"
#define ERR107_BAD_STDOUT_STRLEN "(107) bad stdout strlen"
#define ERR108_STDOUT_READ_BODY "(108) stdout read body"
#define ERR109_STDERR_READ_HEADER "(109 stderr read header"
#define ERR110_BAD_STDERR_STRLEN "(110) bad stderr strlen"
#define ERR111_STDERR_READ_BODY "(111) stderr read body"
#define ERR112_STDOUT_TO_SERVER "(112) error returning stdout to server"
#define ERR113_STDOUT_TO_SERVER "(113) error returning stderr to server"
#define ERR114_UNABLE_TO_OPEN_SOCKET "(114) unable to open socket"
#define ERR115_CONNECTION_REFUSED "(115) connection refused"
#define ERR116_UNABLE_TO_CONNECT "(116) unable to connect"
#define ERR117_LOCK_ERROR_EACCES "(117) lock error: EACCES"
#define ERR118_LOCK_ERROR_EEXIST "(118) lock error: EEXIST"
#define ERR119_LOCK_ERROR_EINVAL "(119) lock error: EINVAL"
#define ERR120_LOCK_ERROR_ENOENT "(120) lock error: ENOENT"
#define ERR121_LOCK_ERROR_ENOSPC "(121) lock error: ENOSPC"
#define ERR122_LOCK_ERROR_OTHER "(122) lock error"
#define ERR123_BAD_ENV_HEADER "(123) bad environment header"
#define ERR124_BAD_STDIN_HEADER "(124) bad stdin header"
/* #define onError(s,x) {estatus=s; emsg=x; goto error;} */
typedef struct resource_tag
{
char sw_info [MAXSZ]; /* path to pcgi info file */
char sw_name [MAXSZ]; /* module name */
char sw_home [MAXSZ]; /* home path */
char sw_exe [MAXSZ]; /* path to executable, e.g. /usr/local/bin/python */
char procpath [MAXSZ]; /* path to file containing pid */
char sockpath [MAXSZ]; /* binding path for UNIX, Win32 named pipes */
char pubpath [MAXSZ]; /* path to pcgi_publisher.py(c) */
int sockport; /* port number, if INET socket */
char sockhost [MAXSZ]; /* hostname, if INET socket */
char modpath [MAXSZ]; /* module path */
char errmsg [MAXSZ]; /* last error, brief message */
char errlog [MAXSZ]; /* fully qualified path to error log file */
char insertPath [MAXPATH]; /* insert path by publisher */
char pythonPath [MAXPATH]; /* PYTHONPATH, if provided */
short displayErrors; /* displayErrors = 0,1 */
long sz_env;
long sz_input;
long sz_output;
long sz_error;
char *p_env;
char *p_input;
char *p_output;
char *p_error;
int procid;
int conn;
int lock;
} pcgiResource;
static char errorHtml[]=
"Status: %s\n"
"Content-Type: text/html\n"
"Pragma: nocache\n"
"Expires: Thu, 01 Dec 1994 16:00:00 GMT\n\n"
"<HTML>\n"
"<HEAD>\n"
"<TITLE>Temporarily Unavailable</TITLE>\n"
"</HEAD>\n"
"<BODY BGCOLOR=\"#FFFFFF\">\n"
"<TABLE BORDER=\"0\" WIDTH=\"100%%\">\n"
"<TR>\n"
" <TD WIDTH=\"10%%\">\n"
" <CENTER>\n"
" <B><FONT SIZE=\"+6\" COLOR=\"#77003B\">!</FONT></B>\n"
" </CENTER>\n"
" </TD>\n"
" <TD WIDTH=\"90%%\"><BR>\n"
" <FONT SIZE=\"+2\">Temporarily Unavailable</FONT>\n"
" <P>\n"
" The resource you requested is temporarily unavailable - "
"please try again later.\n"
" </TD>\n"
"</TR>\n"
"</TABLE>\n"
"%s\n"
"<!--\n%s\n%s\n-->\n"
"</BODY></HTML>";
/* To ensure backward compatibility with pcgi info files, */
/* don't change the order of the first 4 enum elements. */
enum { resource_sockpath=0,
resource_procpath=1,
resource_workdir=2,
resource_modpath=3, /* remaining elements not order dependent */
resource_sockport,
resource_sockhost,
resource_exepath,
resource_exefile,
resource_pubpath,
resource_ENUM };
/* Declarations */
void cleanup(void);
void onError(char *, char *, pcgiResource *);
int pcgiAssignPublisherPath(char *, pcgiResource *);
int pcgiPutEnvironment(char *);
long pcgiRead(pcgi_socket, char *, long);
long pcgiWrite(pcgi_socket, const char *, long);
int pcgiVerifyProc(pcgiResource *);
pcgi_socket pcgiConnect(pcgiResource *);
int pcgiStartProc(pcgiResource *);
int pcgiParseInfo(pcgiResource *);
int pcgiPutNameValueInEnvironment(char *, char *);
void pcgiSIG(int);
void pcgiPrintEnvironment();
void pcgiPrintResourceInfo(pcgiResource *);
int pcgiTruthValue(char);
#ifdef WIN32
void amendPathSeparators(char *);
long pcgiReadSocket(pcgi_socket, char *, long);
long pcgiWriteSocket(pcgi_socket, const char *, long);
#endif
#ifdef HAVE_UNION_SEMUN
#define UNION_SEMUN union semun
#else
#define UNION_SEMUN \
union semun { \
int val; \
struct semid_ds *buf; \
ushort *array; \
} arg;
#endif
#define PCGI_H 1
#endif
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment