]> granicus.if.org Git - php/commitdiff
last bunch of extensions moving to ext/
authorStig Bakken <ssb@php.net>
Thu, 22 Apr 1999 02:48:28 +0000 (02:48 +0000)
committerStig Bakken <ssb@php.net>
Thu, 22 Apr 1999 02:48:28 +0000 (02:48 +0000)
fhttpd module taken out of functions, functions is ready to go.
The only extensions I have tested are gd+freetype and odbc(solid).
Please try compiling in your favourite extensions and let me know how it
works.

85 files changed:
Makefile.in
acconfig.h.in
acinclude.m4
configure.in.in
ext/imap/Makefile.in
ext/informix/Makefile.am
ext/informix/config.h.stub
ext/informix/readme.ifx [new file with mode: 0644]
ext/informix/setup.stub
ext/interbase/Makefile.am [new file with mode: 0644]
ext/interbase/config.h.stub [new file with mode: 0644]
ext/interbase/config.m4 [new file with mode: 0644]
ext/interbase/interbase.c [new file with mode: 0644]
ext/interbase/php3_interbase.h [new file with mode: 0644]
ext/interbase/setup.stub [new file with mode: 0644]
ext/pdf/Makefile.am [new file with mode: 0644]
ext/pdf/config.h.stub [new file with mode: 0644]
ext/pdf/config.m4 [new file with mode: 0644]
ext/pdf/pdf.c [new file with mode: 0644]
ext/pdf/php3_pdf.h [new file with mode: 0644]
ext/pdf/setup.stub [new file with mode: 0644]
ext/pgsql/Makefile.am [new file with mode: 0644]
ext/pgsql/config.h.stub [new file with mode: 0644]
ext/pgsql/config.m4 [new file with mode: 0644]
ext/pgsql/pgsql.c [new file with mode: 0644]
ext/pgsql/php3_pgsql.h [new file with mode: 0644]
ext/pgsql/setup.stub [new file with mode: 0644]
ext/snmp/Makefile.am [new file with mode: 0644]
ext/snmp/Makefile.in [new file with mode: 0644]
ext/snmp/config.h.stub [new file with mode: 0644]
ext/snmp/config.m4 [new file with mode: 0644]
ext/snmp/php3_snmp.h [new file with mode: 0644]
ext/snmp/snmp.c [new file with mode: 0644]
ext/standard/Makefile.am
ext/standard/basic_functions.c
ext/standard/config.h.stub
ext/standard/config.m4
ext/standard/fsock.c
ext/standard/mime.c [new file with mode: 0644]
ext/standard/mime.h [new file with mode: 0644]
ext/standard/php3_standard.h
ext/standard/post.c [new file with mode: 0644]
ext/standard/post.h [new file with mode: 0644]
ext/standard/string.c
ext/standard/var.c
ext/sybase/Makefile.am [new file with mode: 0644]
ext/sybase/Makefile.in [new file with mode: 0644]
ext/sybase/config.h.stub [new file with mode: 0644]
ext/sybase/config.m4 [new file with mode: 0644]
ext/sybase/php3_sybase-ct.h [new file with mode: 0644]
ext/sybase/php3_sybase.h [new file with mode: 0644]
ext/sybase/setup.stub [new file with mode: 0644]
ext/sybase/sybase-ct.c [new file with mode: 0644]
ext/sybase/sybase.c [new file with mode: 0644]
ext/sysvsem/Makefile.am [new file with mode: 0644]
ext/sysvsem/Makefile.in [new file with mode: 0644]
ext/sysvsem/config.h.stub [new file with mode: 0644]
ext/sysvsem/config.m4 [new file with mode: 0644]
ext/sysvsem/php3_sysvsem.h [new file with mode: 0644]
ext/sysvsem/setup.stub [new file with mode: 0644]
ext/sysvsem/sysvsem.c [new file with mode: 0644]
ext/sysvshm/Makefile.am [new file with mode: 0644]
ext/sysvshm/Makefile.in [new file with mode: 0644]
ext/sysvshm/config.h.stub [new file with mode: 0644]
ext/sysvshm/config.m4 [new file with mode: 0644]
ext/sysvshm/php3_sysvshm.h [new file with mode: 0644]
ext/sysvshm/setup.stub [new file with mode: 0644]
ext/sysvshm/sysvshm.c [new file with mode: 0644]
ext/xml/Makefile.am [new file with mode: 0644]
ext/xml/Makefile.in [new file with mode: 0644]
ext/xml/config.h.stub [new file with mode: 0644]
ext/xml/config.m4 [new file with mode: 0644]
ext/xml/php3_xml.h [new file with mode: 0644]
ext/xml/xml.c [new file with mode: 0644]
ext/zlib/Makefile.am [new file with mode: 0644]
ext/zlib/Makefile.in [new file with mode: 0644]
ext/zlib/config.h.stub [new file with mode: 0644]
ext/zlib/config.m4 [new file with mode: 0644]
ext/zlib/php3_zlib.h [new file with mode: 0644]
ext/zlib/setup.stub [new file with mode: 0644]
ext/zlib/zlib.c [new file with mode: 0644]
fhttpd.c [new file with mode: 0644]
internal_functions.c
main/main.c
setup

index 7b4b46c8082a945821f725f7976201a88fa1cc73..11877f1914dd747847340d1a192f54abf949b9c2 100644 (file)
@@ -68,15 +68,8 @@ OBJS = main.o internal_functions.o snprintf.o php3_sprintf.o \
        safe_mode.o fopen-wrappers.o php3_realpath.o alloca.o output.o \
        php_ini.o
 
-FUNCTIONS_SOURCE = functions/fhttpd.c functions/mime.c \
-       functions/pgsql.c functions/post.c functions/sybase.c \
-       functions/sybase-ct.c functions/xml.c functions/zlib.c \
-       functions/pdf.c functions/snmp.c functions/interbase.c \
-       functions/sysvsem.c functions/sysvshm.c
-
-FUNCTIONS = $(FUNCTIONS_SOURCE:.c=.o)
 PHPLIBS = -L@top_srcdir@/libzend -lzend -L@top_srcdir@/ext -lphpext
-LIBS = $(PHPLIBS) $(EXTRA_LIBS) @SYBASE_CT_LFLAGS@ @SYBASE_CT_LIBS@ @FHTTPD_LIB@ @REGEX_LIB@ @DBM_LIB@ @SYBASE_LFLAGS@ @SYBASE_LIBS@ @SYBASE_CT_LFLAGS@ @SYBASE_CT_LIBS@ @PGSQL_LFLAGS@ @PGSQL_LIBS@ @ZLIB_LIBS@ @PDFLIB_LIBS@ @SNMP_LFLAGS@ @SNMP_LIBS@ @IBASE_LFLAGS@ @IBASE_LIBS@ @XML_LIBS@ @LIBS@
+LIBS = $(PHPLIBS) $(EXTRA_LIBS) @LIBS@
 
 all: $(BINNAME)
 
@@ -90,12 +83,12 @@ maintainer-clean-depend-recursive:
        done && test -z "$$fail"
 
 # CGI binary or fhttpd module
-php: all-recursive $(OBJS) $(FUNCTIONS) @REGEX_LIB@ @FHTTPD_LIB@
-       $(CC) $(CFLAGS) -o $(BINNAME) $(LDFLAGS) $(OBJS) $(FUNCTIONS) $(LIBS)
+php: all-recursive $(OBJS) @REGEX_LIB@ @FHTTPD_LIB@
+       $(CC) $(CFLAGS) -o $(BINNAME) $(LDFLAGS) $(OBJS) $(LIBS)
 
 # Apache modules
-libphp3.a libmodphp3.a libmodphp3-so.a: all-recursive $(OBJS) $(FUNCTIONS)
-       $(AR) $@.tmp $(OBJS) $(FUNCTIONS)
+libphp3.a libmodphp3.a libmodphp3-so.a: all-recursive $(OBJS)
+       $(AR) $@.tmp $(OBJS)
        $(srcdir)/scripts/armerge $@ $@.tmp ext/libphpext.a $(srcdir)/libzend/libzend.a
        @rm -f $@.tmp
        $(RANLIB) $(BINNAME)
@@ -118,7 +111,6 @@ configuration-scanner.c:    $(srcdir)/configuration-scanner.l
 
 clean: clean-recursive
        -rm -f libphp3.a libmodphp3.a php *.o
-       -rm -f $(FUNCTIONS) functions/ifx.c
        -rm -f test/php.desc test/php.in test/php.out test/php.test
        -rm -f test/a.tmp test/b.tmp test/test.dbm*
 
@@ -171,8 +163,8 @@ indent:     clean
        -T pval -T HashTable -T Bucket -T Token -T TokenCache -T TokenCacheManager \
        -T switch_expr -T internal_function -T control_structure_data \
        -T MemoryHashTable -T MemoryBucket \
-       -T pvalue_value -T Stack *.c *.h functions/*.c functions/*.h
-       rm -f *~ functions/*~
+       -T pvalue_value -T Stack *.c *.h
+       rm -f *~
 
 .c.o:
        @rm -f $@
@@ -180,11 +172,6 @@ indent:    clean
        @bn=`echo $@ | sed -e 's#functions/##'`; test -f $@ || \
          (test "$@" != "$$bn" && test -f "$$bn" && mv $$bn $@)
 
-functions/number.o: functions/number.c
-       $(CC) $(CFLAGS) -w$(WARNING_LEVEL) -c $< -o $@
-       @bn=`echo $@ | sed -e 's#functions/##'`; test -f $@ || \
-         (test "$@" != "$$bn" && test -f "$$bn" && mv $$bn $@)
-
 parser-scanner:        configuration-parser.c configuration-scanner.c
 
 depend:        parser-scanner
index 7303be1acbc4d009a4f3c1ccf6a9c650bf4499ca..7920bf8d56c964e82cc1b9b690e42f14217a6078 100644 (file)
 /* type check for in_addr_t */
 #undef in_addr_t
 
-/* crypt capability checks */
-#undef PHP3_STD_DES_CRYPT
-#undef PHP3_EXT_DES_CRYPT
-#undef PHP3_MD5_CRYPT
-#undef PHP3_BLOWFISH_CRYPT
-
 /* Define if you have dirent.h but opendir() resides in libc rather than in libdir */
 /* This will cause HAVE_DIRENT_H defined twice sometimes, but it should be problem */
 #define HAVE_DIRENT_H 0
@@ -34,9 +28,6 @@
 /* Define if you have the resolv library (-lresolv). */
 #define HAVE_LIBRESOLV 0
 
-/* Define if you have the zlib library */
-#define HAVE_ZLIB 0
-
 /* Define if you want safe mode enabled by default. */
 #define PHP_SAFE_MODE 0
 
 #define REGEX 0
 #define HSREGEX 0
 
-/* Define if you want the SNMP interface */
-#define HAVE_SNMP 0
-
-/* Define if you have libdl (used for dynamic linking) */
-#define HAVE_LIBDL 0
-
-/* Define if you have libdnet_stub (used for Sybase support) */
-#define HAVE_LIBDNET_STUB 0
-
-/* Define if you have and want to use libcrypt */
-#define HAVE_LIBCRYPT 0
-
 /* Define if you have and want to use libnsl */
 #define HAVE_LIBNSL 0
 
 /* Define if your Apache has src/include/ap_compat.h */
 #define HAVE_AP_COMPAT_H 0
 
-#define HAVE_SYBASE 0
-#define HAVE_SYBASE_CT 0
-
-#ifndef HAVE_PGSQL
-#define HAVE_PGSQL 0
-#endif
-
-#ifndef HAVE_IFX
-#define HAVE_IFX 0
-#endif
-#ifndef HAVE_IFX_IUS
-#define HAVE_IFX_IUS 0
-#endif
-#ifndef IFX_VERSION
-#define IFX_VERSION 0
-#endif
-
-#ifndef HAVE_IBASE
-#define HAVE_IBASE 0
-#endif
-
-#ifndef HAVE_PQCMDTUPLES
-#define HAVE_PQCMDTUPLES 0
-#endif
-
 #ifndef DEBUG /* should be set to ZEND_DEBUG */
 #define DEBUG 0
 #endif
  */
 #define PHP3_URL_FOPEN 0
 
-/* Define if you want System V semaphore support.
- */
-#define HAVE_SYSVSEM 0
-
-/* Define if you have union semun.
- */
-#define HAVE_SEMUN 0
-
-/* Define if you want System V shared memory support.
- */
-#define HAVE_SYSVSHM 0
-
-
 /* Define if you have broken header files like SunOS 4 */
 #define MISSING_FCLOSE_DECL 0
 
 /* Define if you have broken sprintf function like SunOS 4 */
 #define BROKEN_SPRINTF 0
-
-/* Define if you have the expat (XML Parser Toolkit) library */
-#define HAVE_LIBEXPAT 0
-
-/* Define if you have the pdflib library */
-#define HAVE_PDFLIB 0
index c3feedb11b4c2ab9ed9d0555c1a910b358a61753..4b2fbcc876f3a0dd1897333be52cfb9f8201ec63 100644 (file)
@@ -33,103 +33,6 @@ AC_DEFUN(AC_BROKEN_SPRINTF,[
   ])
 ])
 
-dnl
-dnl Check for crypt() capabilities
-dnl
-AC_DEFUN(AC_CRYPT_CAP,[
-
-  AC_MSG_CHECKING([for standard DES crypt])
-  AC_TRY_RUN([
-main() {
-#if HAVE_CRYPT
-    exit (strcmp((char *)crypt("rasmuslerdorf","rl"),"rl.3StKT.4T8M"));
-#else
-       exit(0);
-#endif
-}],[
-    AC_DEFINE(PHP3_STD_DES_CRYPT,1)
-    AC_MSG_RESULT(yes)
-  ],[
-    AC_DEFINE(PHP3_STD_DES_CRYPT,0)
-    AC_MSG_RESULT(no)
-  ],[
-    AC_DEFINE(PHP3_STD_DES_CRYPT,1)
-    AC_MSG_RESULT(cannot check, guessing yes)
-  ])
-
-  AC_MSG_CHECKING([for extended DES crypt])
-  AC_TRY_RUN([
-main() {
-#if HAVE_CRYPT
-    exit (strcmp((char *)crypt("rasmuslerdorf","_J9..rasm"),"_J9..rasmBYk8r9AiWNc"));
-#else
-       exit(0);
-#endif
-}],[
-    AC_DEFINE(PHP3_EXT_DES_CRYPT,1)
-    AC_MSG_RESULT(yes)
-  ],[
-    AC_DEFINE(PHP3_EXT_DES_CRYPT,0)
-    AC_MSG_RESULT(no)
-  ],[
-    AC_DEFINE(PHP3_EXT_DES_CRYPT,0)
-    AC_MSG_RESULT(cannot check, guessing no)
-  ])
-
-  AC_MSG_CHECKING([for MD5 crypt])
-  AC_TRY_RUN([
-main() {
-#if HAVE_CRYPT
-    char salt[15], answer[40];
-
-    salt[0]='$'; salt[1]='1'; salt[2]='$'; 
-    salt[3]='r'; salt[4]='a'; salt[5]='s';
-    salt[6]='m'; salt[7]='u'; salt[8]='s';
-    salt[9]='l'; salt[10]='e'; salt[11]='$';
-    salt[12]='\0';
-    strcpy(answer,salt);
-    strcat(answer,"rISCgZzpwk3UhDidwXvin0");
-    exit (strcmp((char *)crypt("rasmuslerdorf",salt),answer));
-#else
-       exit(0);
-#endif
-}],[
-    AC_DEFINE(PHP3_MD5_CRYPT,1)
-    AC_MSG_RESULT(yes)
-  ],[
-    AC_DEFINE(PHP3_MD5_CRYPT,0)
-    AC_MSG_RESULT(no)
-  ],[
-    AC_DEFINE(PHP3_MD5_CRYPT,0)
-    AC_MSG_RESULT(cannot check, guessing no)
-  ])
-
-  AC_MSG_CHECKING([for Blowfish crypt])
-  AC_TRY_RUN([
-main() {
-#if HAVE_CRYPT
-    char salt[25], answer[70];
-    
-    salt[0]='$'; salt[1]='2'; salt[2]='a'; salt[3]='$'; salt[4]='0'; salt[5]='7'; salt[6]='$'; salt[7]='\0';
-    strcat(salt,"rasmuslerd");
-    strcpy(answer,salt);
-    strcpy(&answer[16],"O............gl95GkTKn53Of.H4YchXl5PwvvW.5ri");
-    exit (strcmp((char *)crypt("rasmuslerdorf",salt),answer));
-#else
-       exit(0);
-#endif
-}],[
-    AC_DEFINE(PHP3_BLOWFISH_CRYPT,1)
-    AC_MSG_RESULT(yes)
-  ],[
-    AC_DEFINE(PHP3_BLOWFISH_CRYPT,0)
-    AC_MSG_RESULT(no)
-  ],[
-    AC_DEFINE(PHP3_BLOWFISH_CRYPT,0)
-    AC_MSG_RESULT(cannot check, guessing no)
-  ])
-])
-
 dnl
 dnl Stuff to do when setting up a new extension.
 dnl XXX have to change the hardcoding of ".a" when we want to be able
index 0ab3f949d0a078e2b898aa6d89b7e7fd2fa7ecde..97d356b82e565ddb314c65a5467f6630651cf19d 100644 (file)
@@ -169,13 +169,6 @@ AC_CHECK_LIB(c, crypt, [:], [
   LIBS="-lcrypt $LIBS"
   AC_DEFINE(HAVE_LIBCRYPT) ], []) ])
 
-AC_CHECK_LIB(c, dlopen, [
- # fake it
- AC_DEFINE(HAVE_LIBDL) ], [
- AC_CHECK_LIB(dl, dlopen, [
-  LIBS="-ldl $LIBS"
-  AC_DEFINE(HAVE_LIBDL) ], []) ])
-
 dnl The sin may be in a library which need not be specifed
 dnl as well as res_search resides in libsocket
 AC_CHECK_LIB(c, sin, [:], [
@@ -263,8 +256,6 @@ if test $ac_cv_type_in_addr_t = no; then
   AC_DEFINE(in_addr_t, u_int)
 fi
 
-AC_CRYPT_CAP
-
 divert(2)
 
 AC_MSG_CHECKING(whether to use bundled regex library)
@@ -295,7 +286,7 @@ AC_ARG_WITH(apxs,
         withval=apxs
     fi
     APXS="$withval"
-    APXS_LDFLAGS="@ORACLE_LFLAGS@ @ORACLE_LIBS@ @SYBASE_LFLAGS@ @SYBASE_LIBS@ @SYBASE_CT_LFLAGS@ @SYBASE_CT_LIBS@ @PGSQL_LFLAGS@ @PGSQL_LIBS@ @LDAP_LFLAGS@ @LDAP_LIBS@ @ZLIB_LIBS@ @PDFLIB_LIBS@ @FDFTK_LIBS@ @IFX_LFLAGS@ @IFX_LIBS@ @IBASE_LFLAGS@ @IBASE_LIBS@"
+    APXS_LDFLAGS="@SYBASE_LFLAGS@ @SYBASE_LIBS@ @SYBASE_CT_LFLAGS@ @SYBASE_CT_LIBS@"
     APACHE_INCLUDE="-I`$APXS -q INCLUDEDIR`"
     BINNAME=libphp3.so
     INSTALL_IT="\$(APXS) -i -a -n php3 $BINNAME"
@@ -792,318 +783,6 @@ AC_SUBST(EXTRA_LIBS)
 # reading config stubs
 esyscmd(./scripts/config-stubs)
 
-AC_MSG_CHECKING(for Sybase support)
-AC_ARG_WITH(sybase,
-[  --with-sybase[=DIR]     Include Sybase-DB support.  DIR is the Sybase home
-                          directory, defaults to /home/sybase.],
-[
-  if test "$withval" != "no"; then
-       if test "$withval" = "yes"; then
-               SYBASE_INCDIR=/home/sybase/include
-               SYBASE_LIBDIR=/home/sybase/lib
-       else
-               SYBASE_INCDIR=$withval/include
-               SYBASE_LIBDIR=$withval/lib
-       fi
-    SYBASE_INCLUDE=-I$SYBASE_INCDIR
-    SYBASE_LFLAGS="-L$SYBASE_LIBDIR -L$SYBASE_LIBDIR"
-    SYBASE_LIBS=-lsybdb
-    AC_MSG_RESULT(yes)
-    AC_CHECK_LIB(dnet_stub, dnet_addr,
-     [ SYBASE_LIBS="$SYBASE_LIBS -ldnet_stub"
-        AC_DEFINE(HAVE_LIBDNET_STUB)
-     ])
-    AC_DEFINE(HAVE_SYBASE)
-  else
-       AC_MSG_RESULT(no)
-  fi
-],[
-  AC_MSG_RESULT(no)
-])
-AC_SUBST(SYBASE_LIBS)
-AC_SUBST(SYBASE_LFLAGS)
-dnl## AC_SUBST(SYBASE_INCLUDE)
-INCLUDES="$INCLUDES $SYBASE_INCLUDE"
-
-AC_MSG_CHECKING(for Sybase-CT support)
-AC_ARG_WITH(sybase-ct,
-[  --with-sybase-ct[=DIR]  Include Sybase-CT support.  DIR is the Sybase home
-                          directory, defaults to /home/sybase.],
-[
-  if test "$withval" != "no"; then
-    AC_MSG_RESULT(yes)
-    AC_DEFINE(HAVE_SYBASE_CT)
-       if test "$withval" = "yes"; then
-               SYBASE_CT_INCDIR=/home/sybase/include
-               SYBASE_CT_LIBDIR=/home/sybase/lib
-       else
-               SYBASE_CT_INCDIR=$withval/include
-               SYBASE_CT_LIBDIR=$withval/lib
-       fi
-    SYBASE_CT_INCLUDE=-I$SYBASE_CT_INCDIR
-    SYBASE_CT_LFLAGS="-L$SYBASE_CT_LIBDIR"
-    SYBASE_CT_LIBS="-lcs -lct -lcomn -lintl"
-    old_LDFLAGS=$LDFLAGS
-    LDFLAGS="$LDFLAGS -L$SYBASE_CT_LIBDIR"
-    AC_CHECK_LIB(tcl, netg_errstr,
-              [ SYBASE_CT_LIBS="$SYBASE_CT_LIBS -ltcl" ],
-              [ SYBASE_CT_LIBS="$SYBASE_CT_LIBS -lsybtcl" ],
-              [ $SYBASE_CT_LIBS ])
-    AC_CHECK_LIB(insck, insck__getVdate,
-              [ SYBASE_CT_LIBS="$SYBASE_CT_LIBS -linsck" ])
-      LDFLAGS=$old_LDFLAGS
-  else
-       AC_MSG_RESULT(no)
-  fi
-],[
-  AC_MSG_RESULT(no)
-])
-AC_SUBST(SYBASE_CT_LIBS)
-AC_SUBST(SYBASE_CT_LFLAGS)
-dnl## AC_SUBST(SYBASE_CT_INCLUDE)
-INCLUDES="$INCLUDES $SYBASE_CT_INCLUDE"
-
-
-AC_MSG_CHECKING(for PostgresSQL support)
-AC_ARG_WITH(pgsql,
-[  --with-pgsql[=DIR]      Include PostgresSQL support.  DIR is the PostgresSQL
-                          base install directory, defaults to /usr/local/pgsql.],
-[
-  if test "$withval" != "no"; then
-       if test "$withval" = "yes"; then
-           PGSQL_INCDIR=/usr/local/pgsql/include
-               PGSQL_LIBDIR=/usr/local/pgsql/lib
-       else
-               PGSQL_INCDIR=$withval/include
-               test -d $withval/include/pgsql && PGSQL_INCDIR=$withval/include/pgsql
-               PGSQL_LIBDIR=$withval/lib
-               test -d $withval/lib/pgsql && PGSQL_LIBDIR=$withval/lib/pgsql
-       fi
-    PGSQL_INCLUDE=-I$PGSQL_INCDIR
-    PGSQL_LFLAGS=-L$PGSQL_LIBDIR
-    PGSQL_LIBS=-lpq
-
-    old_CFLAGS=$CFLAGS; old_LDFLAGS=$LDFLAGS; old_LIBS=$LIBS
-    CFLAGS="$CFLAGS $PGSQL_INCLUDE"
-    LDFLAGS="$LDFLAGS $PGSQL_LFLAGS"
-    LIBS="$LIBS $PGSQL_LIBS"
-    AC_DEFINE(HAVE_PGSQL)
-    AC_MSG_RESULT(yes)
-    AC_CHECK_FUNC(PQcmdTuples,AC_DEFINE(HAVE_PQCMDTUPLES))
-    CFLAGS=$old_CFLAGS; LDFLAGS=$old_LDFLAGS; LIBS=$old_LIBS
-  else
-    AC_MSG_RESULT(no)
-  fi
-],[
-  AC_MSG_RESULT(no)
-])
-AC_SUBST(PGSQL_LIBS)
-AC_SUBST(PGSQL_LFLAGS)
-dnl## AC_SUBST(PGSQL_INCLUDE)
-INCLUDES="$INCLUDES $PGSQL_INCLUDE"
-
-
-AC_MSG_CHECKING(for SNMP support)
-AC_ARG_WITH(snmp,
-[  --with-snmp[=DIR]       Include SNMP support.  DIR is the SNMP base
-                          install directory, defaults to /usr/local],
-[
-  if test "$withval" != "no"; then
-       if test "$withval" = "yes"; then
-               SNMP_INCDIR=/usr/local/include
-               test -d /usr/local/include/ucd-snmp && SNMP_INCDIR=/usr/local/include/ucd-snmp
-               SNMP_LIBDIR=/usr/local/lib
-       else
-               SNMP_INCDIR=$withval/include
-               test -d $withval/include/ucd-snmp && SNMP_INCDIR=$withval/include/ucd-snmp
-               SNMP_LIBDIR=$withval/lib
-       fi
-    SNMP_INCLUDE=-I$SNMP_INCDIR
-    SNMP_LFLAGS=-L$SNMP_LIBDIR
-    SNMP_LIBS="-lsnmp"
-
-    AC_DEFINE(HAVE_SNMP)
-
-    AC_MSG_RESULT(yes)
-  else
-       AC_MSG_RESULT(no)
-  fi
-],[
-  AC_MSG_RESULT(no)
-])
-AC_SUBST(SNMP_LIBS)
-AC_SUBST(SNMP_LFLAGS)
-dnl## AC_SUBST(SNMP_INCLUDE)
-INCLUDES="$INCLUDES $SNMP_INCLUDE"
-
-
-AC_MSG_CHECKING(for InterBase support)
-AC_ARG_WITH(interbase,
-[  --with-interbase[=DIR]  Include InterBase support.  DIR is the InterBase base
-                          install directory, defaults to /usr/interbase],
-[
-  if test "$withval" != "no"; then
-       if test "$withval" = "yes"; then
-               IBASE_INCDIR=/usr/interbase/include
-               IBASE_LIBDIR=/usr/interbase/lib
-       else
-               IBASE_INCDIR=$withval/include
-               IBASE_LIBDIR=$withval/lib
-       fi
-    IBASE_INCLUDE=-I$IBASE_INCDIR
-    IBASE_LFLAGS=-L$IBASE_LIBDIR
-    IBASE_LIBS="-lgds"
-
-    AC_DEFINE(HAVE_IBASE)
-
-    AC_MSG_RESULT(yes)
-  else
-       AC_MSG_RESULT(no)
-  fi
-],[
-  AC_MSG_RESULT(no)
-])
-AC_SUBST(IBASE_LIBS)
-AC_SUBST(IBASE_LFLAGS)
-dnl## AC_SUBST(IBASE_INCLUDE)
-INCLUDES="$INCLUDES $IBASE_INCLUDE"
-
-
-AC_MSG_CHECKING(for XML support)
-AC_ARG_WITH(xml,
-[  --with-xml              Include XML support],[
-  if test "$withval" = "yes"; then
-    AC_DEFINE(HAVE_LIBEXPAT, 1)
-    AC_MSG_RESULT(yes)
-    XML_LIBS="-lexpat"
-  else
-    AC_MSG_RESULT(no)
-  fi
-],[
-  AC_MSG_RESULT(no)
-]) 
-AC_SUBST(XML_LIBS)
-
-
-AC_MSG_CHECKING(whether to include zlib support)
-AC_ARG_WITH(zlib,
-[  --with-zlib[=DIR]       Include zlib support (requires zlib >= 1.0.9).
-                          DIR is the zlib install directory,
-                          defaults to /usr.],
-[
-  case "$withval" in
-    no)
-      AC_MSG_RESULT(no) ;;
-    yes)
-      AC_MSG_RESULT(yes)
-      AC_CHECK_LIB(z, gzgets, [AC_DEFINE(HAVE_ZLIB) ZLIB_LIBS="-lz"],
-        [AC_MSG_ERROR(Zlib module requires zlib >= 1.0.9.)]) ;;
-    *)
-      test -f $withval/include/zlib/zlib.h && ZLIB_INCLUDE="-I$withval/include/zlib"
-      test -f $withval/include/zlib.h && ZLIB_INCLUDE="-I$withval/include"
-      if test -n "$ZLIB_INCLUDE" ; then
-        AC_MSG_RESULT(yes)
-        old_LIBS=$LIBS
-        LIBS="$LIBS -L$withval/lib"
-        AC_CHECK_LIB(z, gzgets, [AC_DEFINE(HAVE_ZLIB) ZLIB_LIBS="-L$withval/lib -lz"],
-          [AC_MSG_ERROR(Zlib module requires zlib >= 1.0.9.)])
-        LIBS=$old_LIBS
-      else
-        AC_MSG_RESULT(no)
-      fi ;;
-  esac
-],[
-  AC_MSG_RESULT(no)
-])
-AC_SUBST(ZLIB_LIBS)
-dnl## AC_SUBST(ZLIB_INCLUDE)
-INCLUDES="$INCLUDES $ZLIB_INCLUDE"
-
-
-AC_MSG_CHECKING(whether to include pdflib support)
-AC_ARG_WITH(pdflib,
-[  --with-pdflib[=DIR]     Include pdflib support (tested with 0.6).
-                          DIR is the pdflib install directory,
-                          defaults to /usr/local.],
-[
-  case "$withval" in
-    no)
-      AC_MSG_RESULT(no) ;;
-    yes)
-      AC_MSG_RESULT(yes)
-      AC_CHECK_LIB(pdf, PDF_open, [AC_DEFINE(HAVE_PDFLIB) PDFLIB_LIBS="-lpdf"],
-        [AC_MSG_ERROR(pdflib module requires pdflib 0.6)]) ;;
-    *)
-      test -f $withval/include/pdf.h && PDFLIB_INCLUDE="-I$withval/include"
-      if test -n "$PDFLIB_INCLUDE" ; then
-        AC_MSG_RESULT(yes)
-        old_LIBS=$LIBS
-        LIBS="$LIBS -L$withval/lib"
-        AC_CHECK_LIB(pdf, PDF_open, [AC_DEFINE(HAVE_PDFLIB) PDFLIB_LIBS="-L$withval/lib -lpdf"],
-          [AC_MSG_ERROR(pdflib module requires pdflib 0.6.)])
-        LIBS=$old_LIBS
-      else
-        AC_MSG_RESULT(no)
-      fi ;;
-  esac
-],[
-  AC_MSG_RESULT(no)
-])
-AC_SUBST(PDFLIB_LIBS)
-dnl## AC_SUBST(PDFLIB_INCLUDE)
-INCLUDES="$INCLUDES $PDFLIB_INCLUDE"
-
-
-AC_MSG_CHECKING(whether to enable System V semaphore support)
-AC_ARG_ENABLE(sysvsem,
-[  --enable-sysvsem        Enable System V semaphore support.],
-[
-  if test "$enableval" = "yes"; then
-    AC_MSG_RESULT(yes)
-    AC_DEFINE(HAVE_SYSVSEM, 1)
-    AC_CACHE_CHECK(for union semun,php_cv_semun,
-           AC_TRY_COMPILE([
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-                       ],
-                       [union semun x;],
-                       [
-                               php_cv_semun=yes
-                       ],[
-                               php_cv_semun=no
-                       ])
-               )
-       if test $php_cv_semun = "yes"; then
-               AC_DEFINE(HAVE_SEMUN, 1)
-       else
-               AC_DEFINE(HAVE_SEMUN, 0)
-       fi
-  else
-    AC_MSG_RESULT(no)
-    AC_DEFINE(HAVE_SYSVSEM, 0)
-  fi
-],[
-  AC_MSG_RESULT(no)
-  AC_DEFINE(HAVE_SYSVSEM, 0)
-])
-
-
-AC_MSG_CHECKING(whether to enable System V shared memory support)
-AC_ARG_ENABLE(sysvshm,
-[  --enable-sysvshm        Enable the System V shared memory support],[
-  if test "$enableval" = "yes"; then
-    AC_DEFINE(HAVE_SYSVSHM, 1)
-    AC_MSG_RESULT(yes)
-  else
-    AC_DEFINE(HAVE_SYSVSHM, 0)
-    AC_MSG_RESULT(no)
-  fi
-],[
-  AC_DEFINE(HAVE_SYSVSHM, 0)
-  AC_MSG_RESULT(no)
-]) 
-
 
 divert(4)
 
@@ -1127,11 +806,6 @@ AC_SUBST(CFLAGS_SHLIB)
 AC_SUBST(LDFLAGS_SHLIB)
 AC_SUBST(LDFLAGS_SHLIB_EXPORT)
 
-dnl Create the necessary directories if building using VPATH
-if test ! -d functions; then
-       mkdir functions
-fi
-
 PHP_BUILD_DATE=`date '+%Y-%m-%d'`
 AC_SUBST(PHP_BUILD_DATE)
 AC_DEFINE_UNQUOTED(PHP_BUILD_DATE,"$PHP_BUILD_DATE")
index d9d006134b0df9abd51be44b44cd590016502b83..e2c360cc603b80909f451890e5edf40b0ff5034a 100644 (file)
@@ -75,18 +75,13 @@ EXT_SUBDIRS = @EXT_SUBDIRS@
 FHTTPD_LIB = @FHTTPD_LIB@
 FHTTPD_TARGET = @FHTTPD_TARGET@
 HSREGEX = @HSREGEX@
-IBASE_LFLAGS = @IBASE_LFLAGS@
-IBASE_LIBS = @IBASE_LIBS@
 INSTALL_IT = @INSTALL_IT@
 LDFLAGS_SHLIB = @LDFLAGS_SHLIB@
 LDFLAGS_SHLIB_EXPORT = @LDFLAGS_SHLIB_EXPORT@
 MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 PACKAGE = @PACKAGE@
-PDFLIB_LIBS = @PDFLIB_LIBS@
 PERL_PATH = @PERL_PATH@
-PGSQL_LFLAGS = @PGSQL_LFLAGS@
-PGSQL_LIBS = @PGSQL_LIBS@
 PHP_BUILD_DATE = @PHP_BUILD_DATE@
 PHP_DEBUG = @PHP_DEBUG@
 PHP_LIBS = @PHP_LIBS@
@@ -95,18 +90,10 @@ PROG_SENDMAIL = @PROG_SENDMAIL@
 RANLIB = @RANLIB@
 RDYNAMIC_LFLAGS = @RDYNAMIC_LFLAGS@
 REGEX_LIB = @REGEX_LIB@
-SNMP_LFLAGS = @SNMP_LFLAGS@
-SNMP_LIBS = @SNMP_LIBS@
 STRONGHOLD = @STRONGHOLD@
-SYBASE_CT_LFLAGS = @SYBASE_CT_LFLAGS@
-SYBASE_CT_LIBS = @SYBASE_CT_LIBS@
-SYBASE_LFLAGS = @SYBASE_LFLAGS@
-SYBASE_LIBS = @SYBASE_LIBS@
 VERSION = @VERSION@
 WARNING_LEVEL = @WARNING_LEVEL@
-XML_LIBS = @XML_LIBS@
 YACC = @YACC@
-ZLIB_LIBS = @ZLIB_LIBS@
 
 INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
 noinst_LIBRARIES=libphpext_imap.a
index 7122ce04f5f2815f8a2c0338e850c8554ef22525..18b8a4fd0855d56305486d251bedaa82734be496 100644 (file)
@@ -10,3 +10,6 @@ ifx.c: ifx.ec
         else \
           touch ifx.c; \
         fi)
+
+clean:
+       -rm -f ifx.c
index 4b90981e7103347c0784678c8f21217caa48af1f..a61d630e4d0951f9137765075f36bcc1557140b6 100644 (file)
@@ -1,2 +1,9 @@
-/* define if you want to use the informix extension */
-/* #undef HAVE_LIBINFORMIX */
+#ifndef HAVE_IFX
+#define HAVE_IFX 0
+#endif
+#ifndef HAVE_IFX_IUS
+#define HAVE_IFX_IUS 0
+#endif
+#ifndef IFX_VERSION
+#define IFX_VERSION 0
+#endif
diff --git a/ext/informix/readme.ifx b/ext/informix/readme.ifx
new file mode 100644 (file)
index 0000000..e69de29
index a7476fb79e37aad51cc805429cd50fdba04020be..9a9d1ad841781da8403081f22dbe45d5b625def8 100644 (file)
@@ -1,6 +1,9 @@
 # $Source$
 # $Id$
 
-define_option with-informix 'informix support?' yesnodir no \
-'    Whether to build the informix extension.'
-       
+define_option with-informix 'Informix support?' yesnodir \
+    "no $INFORMIXDIR Informix home" \
+'    Whether to build PHP with Informix support. If you have not set up your\n
+    Informix environment, enter what $INFORMIXDIR is usually set to here.\n
+    You MUST set $INFORMIXDIR before trying to compile!\n
+    More info about Informix can be found at http://www.informix.com/.'
diff --git a/ext/interbase/Makefile.am b/ext/interbase/Makefile.am
new file mode 100644 (file)
index 0000000..494e3b9
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_interbase.a
+libphpext_interbase_a_SOURCES=interbase.c
+
diff --git a/ext/interbase/config.h.stub b/ext/interbase/config.h.stub
new file mode 100644 (file)
index 0000000..d54ee2a
--- /dev/null
@@ -0,0 +1,3 @@
+#ifndef HAVE_IBASE
+#define HAVE_IBASE 0
+#endif
diff --git a/ext/interbase/config.m4 b/ext/interbase/config.m4
new file mode 100644 (file)
index 0000000..2328e25
--- /dev/null
@@ -0,0 +1,29 @@
+dnl $Id$
+
+AC_MSG_CHECKING(for InterBase support)
+AC_ARG_WITH(interbase,
+[  --with-interbase[=DIR]  Include InterBase support.  DIR is the InterBase base
+                          install directory, defaults to /usr/interbase],
+[
+  if test "$withval" != "no"; then
+    if test "$withval" = "yes"; then
+      IBASE_INCDIR=/usr/interbase/include
+      IBASE_LIBDIR=/usr/interbase/lib
+    else
+      IBASE_INCDIR=$withval/include
+      IBASE_LIBDIR=$withval/lib
+    fi
+    IBASE_INCLUDE=-I$IBASE_INCDIR
+    IBASE_LFLAGS=-L$IBASE_LIBDIR
+    IBASE_LIBS="-lgds"
+    AC_DEFINE(HAVE_IBASE)
+    AC_MSG_RESULT(yes)
+    EXTRA_LIBS="$EXTRA_LIBS $IBASE_LFLAGS $IBASE_LIBS"
+    INCLUDES="$INCLUDES $IBASE_INCLUDE"
+    PHP_EXTENSION(interbase)
+  else
+    AC_MSG_RESULT(no)
+  fi
+],[
+  AC_MSG_RESULT(no)
+])
diff --git a/ext/interbase/interbase.c b/ext/interbase/interbase.c
new file mode 100644 (file)
index 0000000..c239cb6
--- /dev/null
@@ -0,0 +1,1129 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Jouni Ahto <jah@cultnet.fi>                                 |
+   |                                                                      |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/* TODO: A lot... */
+
+#include "config.h"
+#include "php.h"
+#include "php3_interbase.h"
+
+#if HAVE_IBASE
+#include <ibase.h>
+#include <time.h>
+#include "php3_string.h"
+#include "php_globals.h"
+
+/* {{{ extension definition structures */
+function_entry ibase_functions[] = {
+       {"ibase_connect",               php3_ibase_connect,             NULL},
+       {"ibase_pconnect",              php3_ibase_pconnect,    NULL},
+       {"ibase_close",                 php3_ibase_close,               NULL},
+       {"ibase_query",                 php3_ibase_query,               NULL},
+       {"ibase_fetch_row",             php3_ibase_fetch_row,   NULL},
+       {"ibase_free_result",   php3_ibase_free_result, NULL},
+       {"ibase_prepare",               php3_ibase_prepare,             NULL},
+       {"ibase_bind",                  php3_ibase_bind,                NULL},
+       {"ibase_execute",               php3_ibase_execute,             NULL},
+       {"ibase_free_query",    php3_ibase_free_query,  NULL},
+       {"ibase_timefmt",               php3_ibase_timefmt,             NULL},
+       {NULL, NULL, NULL}
+};
+
+php3_module_entry ibase_module_entry =
+{
+       "InterBase",
+       ibase_functions,
+       php3_minit_ibase,
+       NULL,
+       php3_rinit_ibase,
+       NULL,
+       php3_info_ibase,
+       STANDARD_MODULE_PROPERTIES
+};
+/* }}} */
+
+/* {{{ thread safety stuff */
+#if defined(THREAD_SAFE)
+typedef ibase_global_struct{
+        ibase_module php3_ibase_module;
+} ibase_global_struct;
+
+#define IBASE_GLOBAL(a) ibase_globals->a
+
+#define IBASE_TLS_VARS \
+        ibase_global_struct *ibase_globals; \
+        ibase_globals=TlsGetValue(IBASETls); 
+
+#else
+#define IBASE_GLOBAL(a) a
+#define IBASE_TLS_VARS
+ibase_module php3_ibase_module;
+#endif
+/* }}} */
+
+/* {{{ _php3_ibase_close_link() */
+static void _php3_ibase_close_link(isc_db_handle db)
+{
+       ISC_STATUS status[20];
+       IBASE_TLS_VARS;
+
+       isc_detach_database(status, &db);
+       IBASE_GLOBAL(php3_ibase_module).num_links--;
+}
+/* }}} */
+
+/* {{{ _php3_ibase_close_plink() */
+static void _php3_ibase_close_plink(isc_db_handle db)
+{
+       ISC_STATUS status[20];
+       IBASE_TLS_VARS;
+
+       isc_detach_database(status, &db);
+       php3_ibase_module.num_persistent--;
+       php3_ibase_module.num_links--;
+}
+/* }}} */
+
+/* {{{ _php3_ibase_free_result() */
+static void _php3_ibase_free_result(ibase_result_handle *result)
+{
+       int i;
+       ISC_STATUS status[20];
+       IBASE_TLS_VARS;
+
+       if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions && result->commitok) {
+               isc_commit_transaction(status, &result->trans);
+       }
+       if (result->sqlda != NULL) {
+               for (i = 0; i < result->sqlda->sqld; i++) {
+                       efree(result->sqlda->sqlvar[i].sqldata);
+                       efree(result->sqlda->sqlvar[i].sqlind);
+               }
+               efree(result->sqlda);
+       }
+       isc_dsql_free_statement(status, &result->result, DSQL_drop);
+       efree(result);
+}
+/* }}} */
+
+/* {{{ _php3_ibase_free_query() */
+static void _php3_ibase_free_query(ibase_query_handle *query)
+{
+       int i;
+       ISC_STATUS status[20];
+
+       if (query->sqlda != NULL) {
+               if (query->alloced) {
+                       for (i = 0; i < query->sqlda->sqld; i++) {
+                               efree(query->sqlda->sqlvar[i].sqldata);
+                               efree(query->sqlda->sqlvar[i].sqlind);
+                       }
+               }
+               efree(query->sqlda);
+       }
+       isc_dsql_free_statement(status, &query->query, DSQL_drop);
+       efree(query);
+}
+/* }}} */
+
+/* {{{ startup, shutdown and info functions */
+int php3_minit_ibase(INIT_FUNC_ARGS)
+{
+       IBASE_TLS_VARS;
+
+       if (cfg_get_long("ibase.allow_persistent", &IBASE_GLOBAL(php3_ibase_module).allow_persistent) == FAILURE) {
+               IBASE_GLOBAL(php3_ibase_module).allow_persistent = 1;
+       }
+       if (cfg_get_long("ibase.max_persistent", &IBASE_GLOBAL(php3_ibase_module).max_persistent) == FAILURE) {
+               IBASE_GLOBAL(php3_ibase_module).max_persistent = -1;
+       }
+       if (cfg_get_long("ibase.max_links", &IBASE_GLOBAL(php3_ibase_module).max_links) == FAILURE) {
+               IBASE_GLOBAL(php3_ibase_module).max_links = -1;
+       }
+       /*
+       if (cfg_get_long("ibase.manualtransactions", &IBASE_GLOBAL(php3_ibase_module).manualtransactions) == FAILURE) {
+               IBASE_GLOBAL(php3_ibase_module).manualtransactions = 0;
+       }
+       */
+       IBASE_GLOBAL(php3_ibase_module).manualtransactions = 0;
+       if (cfg_get_string("ibase.default_user", &IBASE_GLOBAL(php3_ibase_module).default_user) == FAILURE
+               || IBASE_GLOBAL(php3_ibase_module).default_user[0] == 0) {
+               IBASE_GLOBAL(php3_ibase_module).default_user = "";
+       }
+       if (cfg_get_string("ibase.default_password", &IBASE_GLOBAL(php3_ibase_module).default_password) == FAILURE
+               || IBASE_GLOBAL(php3_ibase_module).default_password[0] == 0) {  
+               IBASE_GLOBAL(php3_ibase_module).default_password = "";
+       }
+       if (cfg_get_string("ibase.timeformat", &IBASE_GLOBAL(php3_ibase_module).timeformat) == FAILURE) {
+               IBASE_GLOBAL(php3_ibase_module).timeformat = "%Y-%m-%d %H:%M:%S";
+       }
+       IBASE_GLOBAL(php3_ibase_module).num_persistent=0;
+       IBASE_GLOBAL(php3_ibase_module).le_result = register_list_destructors(_php3_ibase_free_result, NULL);
+       IBASE_GLOBAL(php3_ibase_module).le_query = register_list_destructors(_php3_ibase_free_query, NULL);
+       IBASE_GLOBAL(php3_ibase_module).le_link = register_list_destructors(_php3_ibase_close_link, NULL);
+       IBASE_GLOBAL(php3_ibase_module).le_plink = register_list_destructors(NULL, _php3_ibase_close_plink);
+       return SUCCESS;
+}
+
+int php3_rinit_ibase(INIT_FUNC_ARGS)
+{
+       IBASE_TLS_VARS;
+
+       IBASE_GLOBAL(php3_ibase_module).default_link=-1;
+       IBASE_GLOBAL(php3_ibase_module).num_links = php3_ibase_module.num_persistent;
+       return SUCCESS;
+}
+
+/* TODO IF NEEDED
+
+int php3_mfinish_ibase(void)
+{
+}
+
+int php3_rfinish_ibase(void)
+{
+}
+*/
+
+void php3_info_ibase(void)
+{
+       /* TODO */
+}
+/* }}} */
+
+/* {{{ _php_ibase_attach_db() */
+static int _php_ibase_attach_db(char *server, char *uname, int uname_len, char *passwd, int passwd_len, isc_db_handle *db)
+{
+       ISC_STATUS status[20];
+       int db_parbuf_len = 4;
+       short foo = 4;
+       char dpb[255], *db_parbuf;
+
+       if (uname_len) {
+               db_parbuf_len += uname_len + 2;
+       }
+
+       if (passwd_len) {
+               db_parbuf_len += passwd_len + 2;
+       }
+
+       db_parbuf = dpb;
+       *db_parbuf++ = isc_dpb_version1;
+       *db_parbuf++ = isc_dpb_num_buffers;
+       *db_parbuf++ = 1;
+       *db_parbuf++ = 90;
+
+       if (uname_len) {
+               if (passwd_len) {
+                       isc_expand_dpb(&db_parbuf, &foo, isc_dpb_user_name, uname, isc_dpb_password, passwd, NULL);
+               } else {
+                       isc_expand_dpb(&db_parbuf, &foo, isc_dpb_user_name, uname, NULL);
+               }
+       }
+
+       isc_attach_database(status, strlen(server), server, db, db_parbuf_len, dpb);
+
+       if (status[0] == 1 && status[1]) {
+               php3_error(E_WARNING,"Unable to connect to InterBase server:  %s", "XXX");
+               return 1;
+       }
+       return 0;
+}
+/* }}} */
+
+/* {{{ _php3_ibase_connect() */
+static void _php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
+{
+       pval *server, *uname, *passwd;
+
+       char *ib_server, *ib_uname, *ib_passwd;
+       int ib_server_len, ib_uname_len, ib_passwd_len;
+       isc_db_handle db_handle = NULL;
+       char *hashed_details;
+       int hashed_details_length;
+       IBASE_TLS_VARS;
+
+       ib_uname = IBASE_GLOBAL(php3_ibase_module).default_user;
+       ib_passwd = IBASE_GLOBAL(php3_ibase_module).default_password;
+       ib_uname_len = ib_uname ? strlen(ib_uname) : 0;
+       ib_passwd_len = ib_passwd ? strlen(ib_passwd) : 0;
+
+       switch(ARG_COUNT(ht)) {
+       case 1:
+               {
+                       if (getParameters(ht, 1, &server) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_string(server);
+                       ib_server = server->value.str.val;
+                       ib_server_len = server->value.str.len;
+                       hashed_details_length = server->value.str.len+ib_uname_len+ib_passwd_len+5+3;
+                       hashed_details = (char *) emalloc(hashed_details_length+1);
+                       sprintf(hashed_details, "ibase_%s_%s_%s", ib_server, ib_uname, ib_passwd);
+               }
+               break;
+       case 2:
+               {
+                       if (getParameters(ht, 2, &server, &uname) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_string(server);
+                       convert_to_string(uname);
+                       ib_server = server->value.str.val;
+                       ib_uname = uname->value.str.val;
+                       ib_server_len = server->value.str.len;
+                       ib_uname_len = uname->value.str.len;
+                       hashed_details_length = server->value.str.len+uname->value.str.len+ib_passwd_len+5+3;
+                       hashed_details = (char *) emalloc(hashed_details_length+1);
+                       sprintf(hashed_details, "ibase_%s_%s_%s", ib_server, ib_uname, ib_passwd);
+               }
+               break;
+       case 3:
+               {
+                       if (getParameters(ht, 3, &server, &uname, &passwd) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_string(server);
+                       convert_to_string(uname);
+                       convert_to_string(passwd);
+                       ib_server = server->value.str.val;
+                       ib_uname = uname->value.str.val;
+                       ib_passwd = passwd->value.str.val;
+                       ib_server_len = server->value.str.len;
+                       ib_uname_len = uname->value.str.len;
+                       ib_passwd_len = passwd->value.str.len;
+                       hashed_details_length = server->value.str.len+uname->value.str.len+passwd->value.str.len+5+3;
+                       hashed_details = (char *) emalloc(hashed_details_length+1);
+                       sprintf(hashed_details, "ibase_%s_%s_%s", ib_server, ib_uname, ib_passwd);
+               }
+               break;
+       default:
+               WRONG_PARAM_COUNT;
+               break;
+       }
+
+       if (persistent) {
+               list_entry *le;
+               
+               if (_php3_hash_find(plist, hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {
+                       list_entry new_le;
+                       
+                       if (IBASE_GLOBAL(php3_ibase_module).max_links!=-1 && IBASE_GLOBAL(php3_ibase_module).num_links>=IBASE_GLOBAL(php3_ibase_module).max_links) {
+                               php3_error(E_WARNING,"InterBase: Too many open links (%d)", IBASE_GLOBAL(php3_ibase_module).num_links);
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       if (IBASE_GLOBAL(php3_ibase_module).max_persistent!=-1 && IBASE_GLOBAL(php3_ibase_module).num_persistent>=IBASE_GLOBAL(php3_ibase_module).max_persistent) {
+                               php3_error(E_WARNING,"InterBase: Too many open persistent links (%d)", IBASE_GLOBAL(php3_ibase_module).num_persistent);
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+
+                       /* create the link */
+
+                       if (_php_ibase_attach_db(ib_server, ib_uname, ib_uname_len, ib_passwd, ib_passwd_len, &db_handle)) {
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+
+                       /* hash it up */
+                       new_le.type = php3_ibase_module.le_plink;
+                       new_le.ptr = db_handle;
+                       if (_php3_hash_update(plist, hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) {
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       IBASE_GLOBAL(php3_ibase_module).num_links++;
+                       IBASE_GLOBAL(php3_ibase_module).num_persistent++;
+               } else {
+                       if (le->type != IBASE_GLOBAL(php3_ibase_module).le_plink) {
+                               RETURN_FALSE;
+                       }
+                       /* TODO: ensure that the link did not die */
+
+                       db_handle = (isc_db_handle) le->ptr;
+               }
+               return_value->value.lval = php3_list_insert(db_handle, IBASE_GLOBAL(php3_ibase_module).le_plink);
+               return_value->type = IS_LONG;
+       } else {
+               list_entry *index_ptr, new_index_ptr;
+               
+               /* first we check the hash for the hashed_details key.  if it exists,
+                * it should point us to the right offset where the actual pgsql link sits.
+                * if it doesn't, open a new pgsql link, add it to the resource list,
+                * and add a pointer to it with hashed_details as the key.
+                */
+               if (_php3_hash_find(list,hashed_details,hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
+                       int type,link;
+                       void *ptr;
+
+                       if (index_ptr->type != le_index_ptr) {
+                               RETURN_FALSE;
+                       }
+                       link = (int) index_ptr->ptr;
+                       ptr = php3_list_find(link,&type);   /* check if the link is still there */
+                       if (ptr && (type==IBASE_GLOBAL(php3_ibase_module).le_link || type==IBASE_GLOBAL(php3_ibase_module).le_plink)) {
+                               return_value->value.lval = IBASE_GLOBAL(php3_ibase_module).default_link = link;
+                               return_value->type = IS_LONG;
+                               efree(hashed_details);
+                               return;
+                       } else {
+                               _php3_hash_del(list,hashed_details,hashed_details_length+1);
+                       }
+               }
+               if (IBASE_GLOBAL(php3_ibase_module).max_links!=-1 && IBASE_GLOBAL(php3_ibase_module).num_links>=IBASE_GLOBAL(php3_ibase_module).max_links) {
+                       php3_error(E_WARNING,"InterBase:  Too many open links (%d)", IBASE_GLOBAL(php3_ibase_module).num_links);
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+               /* create the link */
+
+               if (_php_ibase_attach_db(ib_server, ib_uname, ib_uname_len, ib_passwd, ib_passwd_len, &db_handle)) {
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+
+               /* add it to the list */
+               return_value->value.lval = php3_list_insert(db_handle, IBASE_GLOBAL(php3_ibase_module).le_link);
+               return_value->type = IS_LONG;
+
+               /* add it to the hash */
+               new_index_ptr.ptr = (void *) return_value->value.lval;
+               new_index_ptr.type = le_index_ptr;
+               if (_php3_hash_update(list,hashed_details,hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) {
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+               IBASE_GLOBAL(php3_ibase_module).num_links++;
+       }
+       efree(hashed_details);
+       IBASE_GLOBAL(php3_ibase_module).default_link=return_value->value.lval;
+}
+/* }}} */
+
+/* {{{ proto int ibase_connect(string database [, string username] [, string password])
+   Open a connection to an InterBase database */
+void php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS)
+{
+       _php3_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+/* {{{ proto int ibase_pconnect(string database [, string username] [, string password])
+   Open a persistent connection to an InterBase database */
+void php3_ibase_pconnect(INTERNAL_FUNCTION_PARAMETERS)
+{
+       _php3_ibase_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto int ibase_close([int link_identifier])
+   Close an InterBase connection */
+void php3_ibase_close(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *ibase_link;
+       int id, type;
+       isc_db_handle db_handle;
+       IBASE_TLS_VARS;
+       
+       switch (ARG_COUNT(ht)) {
+               case 0:
+                       id = IBASE_GLOBAL(php3_ibase_module).default_link;
+                       break;
+               case 1:
+                       if (getParameters(ht, 1, &ibase_link) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(ibase_link);
+                       id = ibase_link->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       db_handle = (isc_db_handle) php3_list_find(id, &type);
+       if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
+               php3_error(E_WARNING, "%d is not an InterBase link index",id);
+               RETURN_FALSE;
+       }
+       
+       php3_list_delete(ibase_link->value.lval);
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ _php3_ibase_prepare() */
+static XSQLDA *_php3_ibase_prepare(isc_db_handle db, isc_tr_handle tr, isc_stmt_handle *query_handle, char *query)
+{
+       ISC_STATUS status[20];
+       XSQLDA *isqlda;
+
+       isqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(0));
+    isqlda->sqln = 0;
+    isqlda->version = SQLDA_VERSION1;
+
+       if (isc_dsql_allocate_statement(status, &db, query_handle)) {
+               php3_error(E_WARNING, "InterBase: couldn't allocate space for query");
+               return NULL;
+       }
+
+       if (isc_dsql_prepare(status, &tr, query_handle, 0, query, 1, isqlda)) {
+               php3_error(E_WARNING, "InterBase: couldn't prepare query");
+               return NULL;
+       }
+       
+       /*
+        * Check if query has placeholders and needs binding. If it has, allocate
+        * input sqlda big enough and return it.
+        */
+
+
+       if (isc_dsql_describe_bind(status, query_handle, 1, isqlda)) {
+               php3_error(E_WARNING, "InterBase: couldn't describe placeholders in query");
+       }
+       
+       if (isqlda->sqld > 1) {
+               isqlda = (XSQLDA *) erealloc(isqlda, XSQLDA_LENGTH(isqlda->sqld));
+               isqlda->sqln = isqlda->sqld;
+               isqlda->version = SQLDA_VERSION1;
+               if (isc_dsql_describe(status, query_handle, 1, isqlda)) {
+                       php3_error(E_WARNING, "InterBase: couldn't describe query");
+               }
+               return isqlda;
+       } else if (isqlda->sqld == 1) {
+               return isqlda;
+       } else {
+               efree(isqlda);
+               return NULL;
+       }
+}
+/* }}} */
+
+/* {{{ _php3_ibase_execute() */
+static XSQLDA *_php3_ibase_execute(isc_tr_handle tr_handle, isc_stmt_handle query_handle, XSQLDA *isqlda, ISC_STATUS *status)
+{
+       int i, coltype;
+       static char query_info[] = { isc_info_sql_stmt_type };
+       char info_buffer[18];
+    short l;
+    long query_type;
+       XSQLDA *osqlda;
+
+       /*
+        * Find out what kind of query is to be executed.
+        */
+       
+       if (!isc_dsql_sql_info(status, &query_handle, sizeof(query_info), query_info, sizeof(info_buffer), info_buffer)) {
+               l = (short) isc_vax_integer((char ISC_FAR *) info_buffer + 1, 2);
+               query_type = isc_vax_integer((char ISC_FAR *) info_buffer + 3, l);
+       }
+
+       if (query_type == isc_info_sql_stmt_select || query_type == isc_info_sql_stmt_select_for_upd) {
+               /*
+                * Select, need to allocate output sqlda and and prepare it for use.
+                */
+
+               osqlda = (XSQLDA *) emalloc(XSQLDA_LENGTH(0));
+               osqlda->sqln = 0;
+               osqlda->version = SQLDA_VERSION1;
+
+               if (isc_dsql_describe(status, &query_handle, 1, osqlda)) {
+                       php3_error(E_WARNING, "InterBase: couldn't describe query");
+               }
+
+               if (osqlda->sqld) {
+                       osqlda = (XSQLDA *) erealloc(osqlda, XSQLDA_LENGTH(osqlda->sqld));
+                       osqlda->sqln = osqlda->sqld;
+                       osqlda->version = SQLDA_VERSION1;
+                       if (isc_dsql_describe(status, &query_handle, 1, osqlda)) {
+                               php3_error(E_WARNING, "InterBase: couldn't describe query");
+                       }
+               }
+               for (i = 0; i < osqlda->sqld; i++) {
+                       osqlda->sqlvar[i].sqlind = (short *) emalloc(sizeof(short));
+                       coltype = osqlda->sqlvar[i].sqltype & ~1;
+                       switch(coltype)
+                               {
+                               case SQL_TEXT:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(char)*(osqlda->sqlvar[i].sqllen));
+                                       break;
+                               case SQL_VARYING:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(char)*(osqlda->sqlvar[i].sqllen+2));
+                                       break;
+                               case SQL_SHORT:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(short));
+                                       break;
+                               case SQL_LONG:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(long));
+                                       break;
+                               case SQL_FLOAT:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(float));
+                                       break;
+                               case SQL_DOUBLE:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(double));
+                                       break;
+                               case SQL_DATE:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
+                                       break;
+                               case SQL_BLOB:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
+                                       break;
+                               case SQL_ARRAY:
+                                       osqlda->sqlvar[i].sqldata = (char *) emalloc(sizeof(ISC_QUAD));
+                                       break;
+                               }
+               }
+               if (isqlda == NULL) {
+                       if (isc_dsql_execute(status, &tr_handle, &query_handle, 1, NULL)) {
+                               php3_error(E_WARNING, "InterBase: couldn't execute query");
+                               return NULL;
+                       } else {
+                               return osqlda;
+                       }
+       
+               } else {
+                       if (isc_dsql_execute2(status, &tr_handle, &query_handle, 1, isqlda, osqlda)) {
+                               php3_error(E_WARNING, "InterBase: couldn't execute query");
+                               return NULL;
+                       } else {
+                               return osqlda;
+                       }
+       
+               }
+       } else {
+               /* Not select */
+               if (isc_dsql_execute(status, &tr_handle, &query_handle, 1, isqlda)) {
+                       php3_error(E_WARNING, "InterBase: couldn't execute query");
+               }
+               /*
+               if (!php3_ibase_module.manualtransactions) {
+                       if(0) {
+                               isc_commit_transaction(status, tr_handle);
+                       } else {
+                               isc_rollback_transaction(status, tr_handle);
+                       }
+               }
+               */
+       }
+
+       return NULL;
+}
+/* }}} */
+
+/* {{{ proto int ibase_query([int link_identifier, ]string query)
+   Execute a query (without parameter placeholders). */
+void php3_ibase_query(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *query, *ibase_link;
+       int id, type;
+       isc_db_handle db_handle;
+       isc_tr_handle tr_handle = NULL;
+       isc_stmt_handle query_handle = NULL;
+       ISC_STATUS status[20];
+       XSQLDA *isqlda, *osqlda;
+       ibase_result_handle *ibase_result;
+       IBASE_TLS_VARS;
+
+       switch (ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &query) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       id = IBASE_GLOBAL(php3_ibase_module).default_link;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &ibase_link, &query) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(ibase_link);
+                       id = ibase_link->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       db_handle = (isc_db_handle) php3_list_find(id, &type);
+       if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
+               php3_error(E_WARNING, "%d is not an InterBase link index", id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_string(query);
+
+       if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions) {
+               if (isc_start_transaction(status, &tr_handle, 1, &db_handle, 0, NULL)) {
+                       php3_error(E_WARNING, "InterBase: couldn't start transaction");
+                       RETURN_FALSE;
+               }
+       }
+
+       isqlda = _php3_ibase_prepare(db_handle, tr_handle, &query_handle, query->value.str.val);
+       if (isqlda != NULL) {
+               isc_rollback_transaction(status, &tr_handle);
+               isc_dsql_free_statement(status, &query_handle, DSQL_drop);
+               php3_error(E_WARNING, "InterBase: ibase_query doesn't support parameter placeholders in query");
+               RETURN_FALSE;
+       }
+
+       osqlda = _php3_ibase_execute(tr_handle, query_handle, isqlda, status);
+       if (osqlda != NULL) {
+               ibase_result = (ibase_result_handle *) emalloc(sizeof(ibase_result_handle));
+               ibase_result->result = query_handle;
+               ibase_result->sqlda = osqlda;
+               ibase_result->trans = tr_handle;
+               ibase_result->commitok = 1;
+               return_value->value.lval = php3_list_insert(ibase_result, php3_ibase_module.le_result);
+               return_value->type = IS_LONG;
+       } else {
+               if (status[0] == 1 && status[1]) {
+                       if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions) {
+                               isc_rollback_transaction(status, &tr_handle);
+                               isc_dsql_free_statement(status, &query_handle, DSQL_drop);
+                               RETURN_FALSE;
+                       }
+               } else {
+                       if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions) {
+                               isc_commit_transaction(status, &tr_handle);
+                               isc_dsql_free_statement(status, &query_handle, DSQL_drop);
+                               RETURN_FALSE;
+                       }
+               }
+       }
+}
+/* }}} */
+
+/* {{{ proto int ibase_fetch_row(int result)
+   Fetch a row from the results of a query. */
+void php3_ibase_fetch_row(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result;
+       pval *pval_ptr;
+       int type;
+       int i, coltype, collen;
+       char string_data[255];
+       char *fieldname;
+       char *char_data;
+       /*
+       struct tm t;
+       */
+       ibase_result_handle *ibase_result;
+       ISC_STATUS status[20];
+       XSQLVAR *var;
+       IBASE_VCHAR *vchar;
+       IBASE_TLS_VARS;
+       PLS_FETCH();
+
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       ibase_result = (ibase_result_handle *) php3_list_find(result->value.lval, &type);
+       
+       if (type!=IBASE_GLOBAL(php3_ibase_module).le_result) {
+               php3_error(E_WARNING,"%d is not an InterBase result index", result->value.lval);
+               RETURN_FALSE;
+       }
+
+       if (ibase_result->sqlda == NULL) {
+               php3_error(E_WARNING,"InterBase: trying to fetch results from a non-select query");
+               RETURN_FALSE;
+       }
+
+       var = ibase_result->sqlda->sqlvar;
+
+       if (isc_dsql_fetch(status, &ibase_result->result, 1, ibase_result->sqlda) != 100L) {
+               if (array_init(return_value)==FAILURE) {
+                       RETURN_FALSE;
+               }
+
+               for (i = 0; i < ibase_result->sqlda->sqld; i++) {
+                       var[i].sqlname[var[i].sqlname_length] = '\0';
+                       fieldname = var[i].sqlname;
+                       if (*var[i].sqlind < 0) {
+                               /* XXX. Column is NULL. This is not the best idea to do, think something... */
+                               add_get_index_stringl(return_value, i, NULL, 0, (void **) &pval_ptr, 1);
+                               _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                               continue;
+                       }
+                       coltype = var[i].sqltype & ~1;
+                       switch(coltype) {
+                               case SQL_TEXT:
+                                       {
+                                               int len = var[i].sqllen;
+                                               char_data = (char *)emalloc(sizeof(char)*(var[i].sqllen));
+                                               collen = sprintf(char_data, "%*.*s", len, len, ibase_result->sqlda->sqlvar[i].sqldata);
+                                               if (PG(magic_quotes_runtime)) {
+                                                       int newlen;
+                                                       char *tmp = _php3_addslashes(char_data, collen, &newlen, 0);
+                                                       add_get_index_stringl(return_value, i, tmp, newlen, (void **) &pval_ptr, 0);
+                                               } else {
+                                                       add_get_index_stringl(return_value, i, char_data, collen, (void **) &pval_ptr, 1);
+                                               }
+                                               _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                                               efree(char_data);
+                                       }
+                                       break;
+                               case SQL_VARYING:
+                                       {
+                                               vchar = (IBASE_VCHAR *) var[i].sqldata;
+                                               char_data = (char *)emalloc(sizeof(char)*(vchar->var_len));
+                                               collen = sprintf(char_data, "%*.*s", vchar->var_len, vchar->var_len, vchar->var_str);
+                                               if (PG(magic_quotes_runtime)) {
+                                                       int newlen;
+                                                       char *tmp = _php3_addslashes(char_data, collen, &newlen, 0);
+                                                       add_get_index_stringl(return_value, i, tmp, newlen, (void **) &pval_ptr, 0);
+                                               } else {
+                                                       add_get_index_stringl(return_value, i, char_data, collen, (void **) &pval_ptr, 1);
+                                               }
+                                               _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                                               efree(char_data);
+                                       }
+                                       break;
+                               case SQL_SHORT:
+                                       collen = sprintf(string_data, "%d", *(short *)(var[i].sqldata));
+                                       add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+                                       _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                                       break;
+                               case SQL_LONG:
+                                       if (var[i].sqlscale) {
+                                               int j, f = 1;
+                                               float n;
+                                               n = *(long *)(var[i].sqldata);
+                                               for (j = 0; j < -var[i].sqlscale; j++)
+                                                       f *= 10;
+                                               n /= f;
+                                               collen = sprintf(string_data, "%.*f", -var[i].sqlscale, n);
+
+                                       } else {
+                                               collen = sprintf(string_data, "%ld", *(long *)(var[i].sqldata));
+                                       }
+                                       add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+                                       _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                                       break;
+                               case SQL_FLOAT:
+                                       collen = sprintf(string_data, "%f", *(float *)(var[i].sqldata));
+                                       add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+                                       _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                                       break;
+                               case SQL_DOUBLE:
+                                       if (ibase_result->sqlda->sqlvar[i].sqlscale) {
+                                               collen = sprintf(string_data, "%.*f", -var[i].sqlscale, *(double *)(var[i].sqldata));
+                                       } else {
+                                               collen = sprintf(string_data, "%f", *(double *)(var[i].sqldata));
+                                       }
+                                       add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+                                       _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                                       break;
+                               case SQL_DATE: {
+                                       struct tm *t;
+                                       t = emalloc(sizeof(struct tm));
+
+                                       isc_decode_date((ISC_QUAD *) var[i].sqldata, t);
+                                       /*
+#if HAVE_STRFTIME
+                                       collen = (int) strftime(string_data, 255, IBASE_GLOBAL(php3_ibase_module).timeformat, t);
+#else
+                                       */
+                                       collen = sprintf(string_data, "%4d-%02d-%02d %02d:%02d:%02d", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+                                       /* #endif */
+                                       add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+                                       _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                                       efree(t);
+                                       }
+                                       break;
+                               case SQL_BLOB:
+                               case SQL_ARRAY:
+                                       {
+                                               /* TODO, currently just show the id */
+                                               ISC_QUAD bid;
+                                               bid = *(ISC_QUAD ISC_FAR *) var[i].sqldata;
+                                               sprintf(string_data, "%lx:%lx", bid.isc_quad_high, bid.isc_quad_low);
+                                               add_get_index_stringl(return_value, i, string_data, collen, (void **) &pval_ptr, 1);
+                                               _php3_hash_pointer_update(return_value->value.ht, fieldname, var[i].sqlname_length+1, pval_ptr);
+                                       }
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       } else {
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+/* {{{ proto int ibase_free_result(int result)
+   Free the memory used by a result. */
+void php3_ibase_free_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result;
+       ibase_result_handle *ibase_result;
+       int type;
+       IBASE_TLS_VARS;
+
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       if (result->value.lval==0) {
+               RETURN_FALSE;
+       }
+       
+       ibase_result = (ibase_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=IBASE_GLOBAL(php3_ibase_module).le_result) {
+               php3_error(E_WARNING,"%d is not an InterBase result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       php3_list_delete(result->value.lval);
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int ibase_prepare([int link_identifier, ]string query)
+   Prepare a query for later binding of parameter placeholders and execution. */
+void php3_ibase_prepare(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *query, *ibase_link;
+       int id, type;
+       isc_db_handle db_handle;
+       isc_tr_handle tr_handle = NULL;
+       isc_stmt_handle query_handle = NULL;
+       ISC_STATUS status[20];
+       XSQLDA *isqlda;
+       ibase_query_handle *ibase_query;
+       IBASE_TLS_VARS;
+
+       switch (ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &query) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       id = IBASE_GLOBAL(php3_ibase_module).default_link;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &ibase_link, &query) == FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(ibase_link);
+                       id = ibase_link->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       db_handle = (isc_db_handle) php3_list_find(id, &type);
+       if (type!=IBASE_GLOBAL(php3_ibase_module).le_link && type!=IBASE_GLOBAL(php3_ibase_module).le_plink) {
+               php3_error(E_WARNING, "%d is not an InterBase link index", id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_string(query);
+
+       if (!IBASE_GLOBAL(php3_ibase_module).manualtransactions) {
+               if (isc_start_transaction(status, &tr_handle, 1, &db_handle, 0, NULL)) {
+                       php3_error(E_WARNING, "InterBase: couldn't start transaction");
+                       RETURN_FALSE;
+               }
+       }
+
+       isqlda = _php3_ibase_prepare(db_handle, tr_handle, &query_handle, query->value.str.val);
+       ibase_query = (ibase_query_handle *) emalloc(sizeof(ibase_query_handle));
+       ibase_query->query = query_handle;
+       ibase_query->sqlda = isqlda;
+       ibase_query->trans = tr_handle;
+       ibase_query->alloced = 0;
+       return_value->value.lval = php3_list_insert(ibase_query, php3_ibase_module.le_query);
+       return_value->type = IS_LONG;
+}
+/* }}} */
+
+/* {{{ proto int ibase_bind (int query)
+   Bind parameter placeholders in a previously prepared query. Still nonfunctional. */
+void php3_ibase_bind(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *query;
+       ibase_query_handle *ibase_query;
+       int type;
+       IBASE_TLS_VARS;
+
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &query)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(query);
+       if (query->value.lval==0) {
+               RETURN_FALSE;
+       }
+       
+       ibase_query = (ibase_query_handle *) php3_list_find(query->value.lval,&type);
+       
+       if (type!=IBASE_GLOBAL(php3_ibase_module).le_query) {
+               php3_error(E_WARNING,"%d is not an InterBase query index",query->value.lval);
+               RETURN_FALSE;
+       }
+
+       if (ibase_query->sqlda == NULL) {
+               php3_error(E_WARNING,"InterBase: trying to bind a query having no parameter placeholders");
+               RETURN_FALSE;
+       }
+
+       /* TODO 
+       for (i = 0; i < ibase_query->sqlda->sqld; i++) {
+               ibase_query->sqlda->sqlvar[i].sqlind = (short *) emalloc(sizeof(short));
+               coltype = ibase_query->sqlda->sqlvar[i].sqltype & ~1;
+               switch(coltype)
+                       {
+                       case SQL_TEXT:
+                               break;
+                       case SQL_VARYING:
+                               break;
+                       case SQL_SHORT:
+                               break;
+                       case SQL_LONG:
+                               break;
+                       case SQL_FLOAT:
+                               break;
+                       case SQL_DOUBLE:
+                               break;
+                       case SQL_DATE:
+                               break;
+                       case SQL_BLOB:
+                               break;
+                       case SQL_ARRAY:
+                               break;
+                       }
+       }
+       */
+}
+/* }}} */
+
+/* {{{ proto int ibase_execute(int query)
+   Execute a previously prepared (and possibly binded) query. */
+void php3_ibase_execute(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *query;
+       ibase_query_handle *ibase_query;
+       ibase_result_handle *ibase_result;
+       int type;
+       ISC_STATUS status[20];
+       XSQLDA *osqlda;
+       IBASE_TLS_VARS;
+
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &query)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(query);
+       if (query->value.lval==0) {
+               RETURN_FALSE;
+       }
+       
+       ibase_query = (ibase_query_handle *) php3_list_find(query->value.lval,&type);
+       
+       if (type!=IBASE_GLOBAL(php3_ibase_module).le_query) {
+               php3_error(E_WARNING,"%d is not an InterBase query index", query->value.lval);
+               RETURN_FALSE;
+       }
+
+       osqlda = _php3_ibase_execute(ibase_query->trans, ibase_query->query, ibase_query->sqlda, status);
+       ibase_result = (ibase_result_handle *) emalloc(sizeof(ibase_result_handle));
+       ibase_result->result = ibase_query->query;
+       ibase_result->sqlda = osqlda;
+       return_value->value.lval = php3_list_insert(ibase_result, IBASE_GLOBAL(php3_ibase_module).le_result);
+       return_value->type = IS_LONG;
+}
+/* }}} */
+
+/* {{{ proto int ibase_free_query(int query)
+   Free memory used by a query */
+void php3_ibase_free_query(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *query;
+       ibase_query_handle *ibase_query;
+       int type;
+       IBASE_TLS_VARS;
+
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &query)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(query);
+       if (query->value.lval==0) {
+               RETURN_FALSE;
+       }
+       
+       ibase_query = (ibase_query_handle *) php3_list_find(query->value.lval, &type);
+       
+       if (type!=IBASE_GLOBAL(php3_ibase_module).le_query) {
+               php3_error(E_WARNING,"%d is not an InterBase query index", query->value.lval);
+               RETURN_FALSE;
+       }
+       php3_list_delete(query->value.lval);
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int ibase_timefmt(string format)
+   Sets the format of datetime columns returned from queries. Still nonfunctional. */
+void php3_ibase_timefmt(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pmode;
+       IBASE_TLS_VARS;
+
+#if HAVE_STRFTIME
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &pmode)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_string(pmode);
+
+       RETURN_TRUE;
+#else
+       php3_error(E_WARNING,"InterBase: ibase_timefmt not supported on this platform");
+       RETURN_FALSE;
+#endif
+}
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/interbase/php3_interbase.h b/ext/interbase/php3_interbase.h
new file mode 100644 (file)
index 0000000..47da79d
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Jouni Ahto <jah@cultnet.fi>                                 |
+   |                                                                      |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef _PHP3_IBASE_H
+#define _PHP3_IBASE_H
+
+#if COMPILE_DL
+#undef HAVE_IBASE
+#define HAVE_IBASE 1
+#endif
+
+#if HAVE_IBASE
+#include <ibase.h>
+
+extern php3_module_entry ibase_module_entry;
+#define php3_ibase_module_ptr &ibase_module_entry
+
+extern int php3_minit_ibase(INIT_FUNC_ARGS);
+extern int php3_rinit_ibase(INIT_FUNC_ARGS);
+extern int php3_mfinish_ibase(void);
+extern void php3_info_ibase(void);
+extern void php3_ibase_connect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_pconnect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_close(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_query(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_fetch_row(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_free_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_prepare(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_bind(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_execute(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_free_query(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_ibase_timefmt(INTERNAL_FUNCTION_PARAMETERS);
+
+typedef struct {
+       long default_link;
+       long num_links, num_persistent;
+       long max_links, max_persistent;
+       long allow_persistent;
+       int le_link, le_plink, le_result, le_query;
+       char *default_user, *default_password;
+       long manualtransactions;
+       char *timeformat;
+} ibase_module;
+
+typedef struct _php3_ibase_result {
+       isc_stmt_handle result;
+       isc_tr_handle trans;
+       XSQLDA *sqlda;
+       int commitok;
+} ibase_result_handle;
+
+typedef struct _php3_ibase_query {
+       isc_stmt_handle query;
+       isc_tr_handle trans;
+       XSQLDA *sqlda;
+       int alloced;
+} ibase_query_handle;
+
+typedef struct _php3_ibase_varchar {
+    short var_len;
+    char var_str[1];
+} IBASE_VCHAR;
+
+extern ibase_module php3_ibase_module;
+
+#else
+
+#define php3_ibase_module_ptr NULL
+
+#endif /* HAVE_IBASE */
+
+#endif /* _PHP3_IBASE_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/interbase/setup.stub b/ext/interbase/setup.stub
new file mode 100644 (file)
index 0000000..3c6a41f
--- /dev/null
@@ -0,0 +1,7 @@
+# $Source$
+# $Id$
+
+define_option with-interbase 'InterBase support?' yesnodir \
+    'no /usr/interbase InterBase base install' \
+'     Whether to build PHP with InterBase support. More\n
+      information about InterBase can be found at http://www.interbase.com/.'
diff --git a/ext/pdf/Makefile.am b/ext/pdf/Makefile.am
new file mode 100644 (file)
index 0000000..6b4304d
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_pdf.a
+libphpext_pdf_a_SOURCES=pdf.c
+
diff --git a/ext/pdf/config.h.stub b/ext/pdf/config.h.stub
new file mode 100644 (file)
index 0000000..11c404a
--- /dev/null
@@ -0,0 +1,2 @@
+/* Define if you have the pdflib library */
+#define HAVE_PDFLIB 0
diff --git a/ext/pdf/config.m4 b/ext/pdf/config.m4
new file mode 100644 (file)
index 0000000..c421e2a
--- /dev/null
@@ -0,0 +1,37 @@
+dnl $Id$
+
+AC_MSG_CHECKING(whether to include pdflib support)
+AC_ARG_WITH(pdflib,
+[  --with-pdflib[=DIR]     Include pdflib support (tested with 0.6).
+                          DIR is the pdflib install directory,
+                          defaults to /usr/local.],
+[
+  case "$withval" in
+    no)
+      AC_MSG_RESULT(no) ;;
+    yes)
+      AC_MSG_RESULT(yes)
+      PHP_EXTENSION(pdf)
+      AC_CHECK_LIB(pdf, PDF_open, [AC_DEFINE(HAVE_PDFLIB) PDFLIB_LIBS="-lpdf"],
+        [AC_MSG_ERROR(pdflib extension requires pdflib 0.6.)])
+      EXTRA_LIBS="$EXTRA_LIBS $PDFLIB_LIBS"
+      ;;
+    *)
+      test -f $withval/include/pdf.h && PDFLIB_INCLUDE="-I$withval/include"
+      if test -n "$PDFLIB_INCLUDE" ; then
+        AC_MSG_RESULT(yes)
+        PHP_EXTENSION(pdf)
+        old_LIBS=$LIBS
+        LIBS="$LIBS -L$withval/lib"
+        AC_CHECK_LIB(pdf, PDF_open, [AC_DEFINE(HAVE_PDFLIB) PDFLIB_LIBS="-L$withval/lib -lpdf"],
+          [AC_MSG_ERROR(pdflib extension requires pdflib 0.6.)])
+        LIBS=$old_LIBS
+        EXTRA_LIBS="$EXTRA_LIBS $PDFLIB_LIBS"
+        INCLUDES="$INCLUDES $PDFLIB_INCLUDE"
+      else
+        AC_MSG_RESULT(no)
+      fi ;;
+  esac
+],[
+  AC_MSG_RESULT(no)
+])
diff --git a/ext/pdf/pdf.c b/ext/pdf/pdf.c
new file mode 100644 (file)
index 0000000..2e90f5a
--- /dev/null
@@ -0,0 +1,1797 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Uwe Steinmann <Uwe.Steinmann@fernuni-hagen.de>              |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+/* pdflib 0.6 is subject to the ALADDIN FREE PUBLIC LICENSE.
+   Copyright (C) 1997 Thomas Merz. */
+
+/* Note that there is no code from the pdflib package in this file */
+
+#if !PHP_31 && defined(THREAD_SAFE)
+#undef THREAD_SAFE
+#endif
+
+#include "php.h"
+#include "ext/standard/head.h"
+#include <math.h>
+#include "php3_pdf.h"
+
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#if WIN32|WINNT
+# include <io.h>
+# include <fcntl.h>
+#endif
+
+#if HAVE_PDFLIB
+
+#ifdef THREAD_SAFE
+DWORD PDFlibTls;
+static int numthreads=0;
+
+typedef struct pdflib_global_struct{
+       int le_pdf_info;
+       int le_pdf;
+} pdflib_global_struct;
+
+# define PDF_GLOBAL(a) pdflib_globals->a
+# define PDF_TLS_VARS pdflib_global_struct *pdflib_globals=TlsGetValue(PDFlibTls)
+
+#else
+#  define PDF_GLOBAL(a) a
+#  define PDF_TLS_VARS
+int le_pdf_info;
+int le_pdf;
+#endif
+
+function_entry pdf_functions[] = {
+       {"pdf_get_info",                        php3_pdf_get_info,                      NULL},
+       {"pdf_set_info_creator",        php3_pdf_set_info_creator,      NULL},
+       {"pdf_set_info_title",          php3_pdf_set_info_title,        NULL},
+       {"pdf_set_info_subject",        php3_pdf_set_info_subject,      NULL},
+       {"pdf_set_info_author",         php3_pdf_set_info_author,       NULL},
+       {"pdf_set_info_keywords",       php3_pdf_set_info_keywords,     NULL},
+       {"pdf_open",                            php3_pdf_open,                          NULL},
+       {"pdf_close",                           php3_pdf_close,                         NULL},
+       {"pdf_begin_page",                      php3_pdf_begin_page,            NULL},
+       {"pdf_end_page",                        php3_pdf_end_page,                      NULL},
+       {"pdf_show",                            php3_pdf_show,                          NULL},
+       {"pdf_show_xy",                         php3_pdf_show_xy,                       NULL},
+       {"pdf_set_font",                        php3_pdf_set_font,                      NULL},
+       {"pdf_set_leading",                     php3_pdf_set_leading,           NULL},
+       {"pdf_set_text_rendering",      php3_pdf_set_text_rendering,NULL},
+       {"pdf_set_horiz_scaling",       php3_pdf_set_horiz_scaling,     NULL},
+       {"pdf_set_text_rise",           php3_pdf_set_text_rise,         NULL},
+       {"pdf_set_text_matrix",         php3_pdf_set_text_matrix,       NULL},
+       {"pdf_set_text_pos",            php3_pdf_set_text_pos,          NULL},
+       {"pdf_set_char_spacing",                php3_pdf_set_char_spacing,              NULL},
+       {"pdf_set_word_spacing",                php3_pdf_set_word_spacing,              NULL},
+       {"pdf_continue_text",           php3_pdf_continue_text,         NULL},
+       {"pdf_stringwidth",             php3_pdf_stringwidth,           NULL},
+       {"pdf_save",                            php3_pdf_save,                          NULL},
+       {"pdf_restore",                         php3_pdf_restore,                       NULL},
+       {"pdf_translate",                       php3_pdf_translate,                     NULL},
+       {"pdf_scale",                           php3_pdf_scale,                         NULL},
+       {"pdf_rotate",                          php3_pdf_rotate,                        NULL},
+       {"pdf_setflat",                         php3_pdf_setflat,                       NULL},
+       {"pdf_setlinejoin",                     php3_pdf_setlinejoin,           NULL},
+       {"pdf_setlinecap",                      php3_pdf_setlinecap,            NULL},
+       {"pdf_setmiterlimit",           php3_pdf_setmiterlimit,         NULL},
+       {"pdf_setlinewidth",            php3_pdf_setlinewidth,          NULL},
+       {"pdf_setdash",                         php3_pdf_setdash,                       NULL},
+       {"pdf_moveto",                          php3_pdf_moveto,                        NULL},
+       {"pdf_lineto",                          php3_pdf_lineto,                        NULL},
+       {"pdf_curveto",                         php3_pdf_curveto,                       NULL},
+       {"pdf_circle",                          php3_pdf_circle,                        NULL},
+       {"pdf_arc",                                     php3_pdf_arc,                           NULL},
+       {"pdf_rect",                            php3_pdf_rect,                          NULL},
+       {"pdf_closepath",                       php3_pdf_closepath,                     NULL},
+       {"pdf_stroke",                          php3_pdf_stroke,                        NULL},
+       {"pdf_closepath_stroke",        php3_pdf_closepath_stroke,      NULL},
+       {"pdf_fill",                            php3_pdf_fill,                          NULL},
+       {"pdf_fill_stroke",                     php3_pdf_fill_stroke,           NULL},
+       {"pdf_closepath_fill_stroke",   php3_pdf_closepath_fill_stroke, NULL},
+       {"pdf_endpath",                         php3_pdf_endpath,                       NULL},
+       {"pdf_clip",                            php3_pdf_clip,                          NULL},
+       {"pdf_setgray_fill",            php3_pdf_setgray_fill,          NULL},
+       {"pdf_setgray_stroke",          php3_pdf_setgray_stroke,        NULL},
+       {"pdf_setgray",                         php3_pdf_setgray,                       NULL},
+       {"pdf_setrgbcolor_fill",        php3_pdf_setrgbcolor_fill,      NULL},
+       {"pdf_setrgbcolor_stroke",      php3_pdf_setrgbcolor_stroke,NULL},
+       {"pdf_setrgbcolor",                     php3_pdf_setrgbcolor,           NULL},
+       {"pdf_add_outline",                     php3_pdf_add_outline,           NULL},
+       {"pdf_set_transition",                  php3_pdf_set_transition,                NULL},
+       {"pdf_set_duration",                    php3_pdf_set_duration,          NULL},
+       {NULL, NULL, NULL}
+};
+
+php3_module_entry pdf_module_entry = {
+       "pdf", pdf_functions, php3_minit_pdf, php3_mend_pdf, NULL, NULL, php3_info_pdf, STANDARD_MODULE_PROPERTIES
+};
+
+#if COMPILE_DL
+#include "dl/phpdl.h"
+DLEXPORT php3_module_entry *get_module(void) { return &pdf_module_entry; }
+#endif
+
+static void _free_pdf_info(PDF_info *info)
+{
+       if(info->Title) efree(info->Title);
+       if(info->Subject) efree(info->Subject);
+       if(info->Author) efree(info->Author);
+       if(info->Keywords) efree(info->Keywords);
+       if(info->Creator) efree(info->Creator);
+}
+
+int php3_minit_pdf(INIT_FUNC_ARGS)
+{
+       PDF_GLOBAL(le_pdf_info) = register_list_destructors(_free_pdf_info, NULL);
+       PDF_GLOBAL(le_pdf) = register_list_destructors(php3_pdf_close, NULL);
+       return SUCCESS;
+}
+
+void php3_info_pdf(void) {
+       /* need to use a PHPAPI function here because it is external module in windows */
+       php3_printf("%s. AFM files in %s", PDFLIB_VERSION, PDF_DEFAULT_FONT_PATH);
+}
+
+int php3_mend_pdf(void){
+       return SUCCESS;
+}
+
+/* {{{ proto int pdf_get_info(void)
+   Returns a default info structure for a pdf document */
+void php3_pdf_get_info(INTERNAL_FUNCTION_PARAMETERS) {
+       PDF_info *pdf_info;
+       int id;
+       PDF_TLS_VARS;
+
+       pdf_info = PDF_get_info();
+
+       if(!pdf_info) {
+               php3_error(E_WARNING, "Could not get PDF info");
+               RETURN_FALSE;
+       }
+
+       id = php3_list_insert(pdf_info,PDF_GLOBAL(le_pdf_info));
+       RETURN_LONG(id);
+}
+/* }}} */
+
+/* {{{ proto pdf_set_info_creator(int info, string creator)
+   Fills the creator field of the info structure */
+void php3_pdf_set_info_creator(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF_info *pdf_info;
+       PDF_TLS_VARS;
+
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf_info = php3_list_find(id,&type);
+       if (!pdf_info || type!=PDF_GLOBAL(le_pdf_info)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d (type=%d)",id, type);
+               RETURN_FALSE;
+       }
+
+       pdf_info->Creator = estrdup(arg2->value.str.val);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto pdf_set_info_title(int info, string title)
+   Fills the title field of the info structure */
+void php3_pdf_set_info_title(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF_info *pdf_info;
+       PDF_TLS_VARS;
+
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf_info = php3_list_find(id,&type);
+       if (!pdf_info || type!=PDF_GLOBAL(le_pdf_info)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d (type=%d)",id, type);
+               RETURN_FALSE;
+       }
+
+       pdf_info->Title = estrdup(arg2->value.str.val);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto pdf_set_info_subject(int info, string subject)
+   Fills the subject field of the info structure */
+void php3_pdf_set_info_subject(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF_info *pdf_info;
+       PDF_TLS_VARS;
+
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf_info = php3_list_find(id,&type);
+       if (!pdf_info || type!=PDF_GLOBAL(le_pdf_info)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d (type=%d)",id, type);
+               RETURN_FALSE;
+       }
+
+       pdf_info->Subject = estrdup(arg2->value.str.val);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto pdf_set_info_author(int info, string author)
+   Fills the author field of the info structure */
+void php3_pdf_set_info_author(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF_info *pdf_info;
+       PDF_TLS_VARS;
+
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf_info = php3_list_find(id,&type);
+       if (!pdf_info || type!=PDF_GLOBAL(le_pdf_info)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d (type=%d)",id, type);
+               RETURN_FALSE;
+       }
+
+       pdf_info->Author = estrdup(arg2->value.str.val);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto pdf_set_info_keywords(int info, string keywords)
+   Fills the keywords field of the info structure */
+void php3_pdf_set_info_keywords(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF_info *pdf_info;
+       PDF_TLS_VARS;
+
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf_info = php3_list_find(id,&type);
+       if (!pdf_info || type!=PDF_GLOBAL(le_pdf_info)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d (type=%d)",id, type);
+               RETURN_FALSE;
+       }
+
+       pdf_info->Keywords = estrdup(arg2->value.str.val);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int pdf_open(int filedesc, int info)
+   Opens a new pdf document */
+void php3_pdf_open(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *file;
+       pval *info;
+       int id, type;
+       FILE *fp;
+       PDF_info *pdf_info;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &file, &info) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(file);
+       convert_to_long(info);
+       id=file->value.lval;
+       fp = php3_list_find(id,&type);
+       if (!fp || type!=php3i_get_le_fp()) {
+               php3_error(E_WARNING,"Unable to find file identifier %d (type=%d)",id, type);
+               RETURN_FALSE;
+       }
+
+       id=info->value.lval;
+       pdf_info = php3_list_find(id,&type);
+       if (!pdf_info || type!=PDF_GLOBAL(le_pdf_info)) {
+               php3_error(E_WARNING,"Unable to find pdf info identifier %d (%d!=%d)",id, type, PDF_GLOBAL(le_pdf_info));
+               RETURN_FALSE;
+       }
+
+       pdf = PDF_open(fp, pdf_info);
+       if(!pdf)
+               RETURN_FALSE;
+
+       id = php3_list_insert(pdf,PDF_GLOBAL(le_pdf));
+       RETURN_LONG(id);
+}
+/* }}} */
+
+/* {{{ proto void pdf_close(int pdfdoc)
+   Closes the pdf document */
+void php3_pdf_close(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_close(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_begin_page(int pdfdoc, double height, double width)
+   Starts page */
+void php3_pdf_begin_page(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3;
+       int id, type;
+       double height, width;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       id=arg1->value.lval;
+       height = arg2->value.dval;
+       width = arg3->value.dval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_begin_page(pdf, (float) height, (float) width);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_end_page(int pdfdoc)
+   Ends page */
+void php3_pdf_end_page(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_end_page(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_show(int pdfdoc, string text)
+   Output text at current position */
+void php3_pdf_show(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_show(pdf, arg2->value.str.val);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_show_xy(int pdfdoc, string text)
+   Output text at position */
+void php3_pdf_show_xy(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       convert_to_double(arg3);
+       convert_to_double(arg4);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_show_xy(pdf, arg2->value.str.val, (float) arg3->value.dval, (float) arg4->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_font(int pdfdoc, string font, double size, string encoding)
+   Select the current font face and size */
+void php3_pdf_set_font(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       convert_to_double(arg3);
+       convert_to_string(arg4);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+       
+       PDF_set_font(pdf, arg2->value.str.val, (float) arg3->value.dval, builtin);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_leading(int pdfdoc, double distance)
+   Sets distance between text lines */
+void php3_pdf_set_leading(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+       
+       PDF_set_leading(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_text_rendering(int pdfdoc, int mode)
+   Determines how text is rendered */
+void php3_pdf_set_text_rendering(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_long(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+       
+       PDF_set_text_rendering(pdf, (byte) arg2->value.lval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_horiz_scaling(int pdfdoc, double scale)
+   Sets horizontal scaling of text */
+void php3_pdf_set_horiz_scaling(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+       
+       PDF_set_horiz_scaling(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_text_rise(int pdfdoc, double value)
+   Sets the text rise */
+void php3_pdf_set_text_rise(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+       
+       PDF_set_text_rise(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_text_matrix(int pdfdoc, arry matrix)
+   Sets the text matrix */
+void php3_pdf_set_text_matrix(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *data;
+       int id, type, i;
+       HashTable *matrix;
+       PDF *pdf;
+       PDF_matrix pdfmatrix;
+       float *pdfmatrixptr;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_array(arg2);
+       id=arg1->value.lval;
+       matrix=arg2->value.ht;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+       
+       if(_php3_hash_num_elements(matrix) != 6) {
+                php3_error(E_WARNING,"Text matrix must have 6 elements");
+               RETURN_FALSE;
+       }
+
+       pdfmatrixptr = (float *) &pdfmatrix;
+       _php3_hash_internal_pointer_reset(matrix);
+       for(i=0; i<_php3_hash_num_elements(matrix); i++) {
+               _php3_hash_get_current_data(matrix, (void *) &data);
+               switch(data->type) {
+                       case IS_DOUBLE:
+                               *pdfmatrixptr++ = (float) data->value.dval;
+                       default:
+                               *pdfmatrixptr++ = 0.0;
+               }
+               _php3_hash_move_forward(matrix);
+       }
+
+       PDF_set_text_matrix(pdf, pdfmatrix);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_text_pos(int pdfdoc, double x, double y)
+   */
+void php3_pdf_set_text_pos(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_set_text_pos(pdf, (float) arg2->value.dval, (float) arg3->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_char_spacing(int pdfdoc, double space)
+   Sets character spacing */
+void php3_pdf_set_char_spacing(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_set_char_spacing(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_word_spacing(int pdfdoc, double space)
+   Sets spacing between words */
+void php3_pdf_set_word_spacing(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_set_word_spacing(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_continue_text(int pdfdoc, string text)
+   Output text in next line */
+void php3_pdf_continue_text(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_continue_text(pdf, arg2->value.str.val);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto double pdf_stringwidth(int pdfdoc, string text)
+   Returns width of text in current font*/
+void php3_pdf_stringwidth(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       double width;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       width = (double) PDF_stringwidth(pdf, arg2->value.str.val);
+
+       RETURN_DOUBLE((double)width);
+}
+/* }}} */
+
+/* {{{ proto void pdf_save(int pdfdoc)
+   Saves current enviroment */
+void php3_pdf_save(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_save(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_restore(int pdfdoc)
+   Restores formerly saved enviroment */
+void php3_pdf_restore(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_restore(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_translate(int pdfdoc, double x, double y)
+   Sets origin of coordinate system */
+void php3_pdf_translate(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_translate(pdf, (float) arg2->value.dval, (float) arg3->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_scale(int pdfdoc, double x-scale, double y-scale)
+   Sets scaling */
+void php3_pdf_scale(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_scale(pdf, (float) arg2->value.dval, (float) arg3->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_rotate(int pdfdoc, double angle)
+   Sets rotation */
+void php3_pdf_rotate(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_rotate(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setflat(int pdfdoc, double value)
+   Sets flatness */
+void php3_pdf_setflat(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       if((arg2->value.lval > 100) && (arg2->value.lval < 0)) {
+               php3_error(E_WARNING,"Parameter of pdf_setflat() has to between 0 and 100");
+               RETURN_FALSE;
+       }
+
+       PDF_setflat(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setlinejoin(int pdfdoc, int value)
+   Sets linejoin parameter */
+void php3_pdf_setlinejoin(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_long(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       if((arg2->value.lval > 2) && (arg2->value.lval < 0)) {
+               php3_error(E_WARNING,"Parameter of pdf_setlinejoin() has to between 0 and 2");
+               RETURN_FALSE;
+       }
+
+       PDF_setlinejoin(pdf, (byte) arg2->value.lval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setlinecap(int pdfdoc, int value)
+   Sets linecap parameter */
+void php3_pdf_setlinecap(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_long(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       if((arg2->value.lval > 2) && (arg2->value.lval < 0)) {
+               php3_error(E_WARNING,"Parameter of pdf_setlinecap() has to be > 0 and =< 2");
+               RETURN_FALSE;
+       }
+
+       PDF_setlinecap(pdf, (byte) arg2->value.lval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setmiterlimit(int pdfdoc, double value)
+   Sets miter limit */
+void php3_pdf_setmiterlimit(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       if(arg2->value.dval < 1) {
+               php3_error(E_WARNING,"Parameter of pdf_setmiterlimit() has to be >= 1");
+               RETURN_FALSE;
+       }
+
+       PDF_setmiterlimit(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setlinewidth(int pdfdoc, double width)
+   Sets line width */
+void php3_pdf_setlinewidth(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_setlinewidth(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setdash(int pdfdoc, double white, double black)
+   Sets dash pattern */
+void php3_pdf_setdash(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_setdash(pdf, (float) arg2->value.dval, (float) arg3->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_moveto(int pdfdoc, double x, double y)
+   Sets current point */
+void php3_pdf_moveto(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_moveto(pdf, (float) arg2->value.dval, (float) arg3->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_curveto(int pdfdoc, double x1, double y1, double x2, double y2, double x3, double y3)
+   Draws a curve */
+void php3_pdf_curveto(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4, *arg5, *arg6, *arg7;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 7 || getParameters(ht, 7, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       convert_to_double(arg4);
+       convert_to_double(arg5);
+       convert_to_double(arg6);
+       convert_to_double(arg7);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_curveto(pdf, (float) arg2->value.dval,
+                       (float) arg3->value.dval,
+                       (float) arg4->value.dval,
+                       (float) arg5->value.dval,
+                       (float) arg6->value.dval,
+                       (float) arg7->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_lineto(int pdfdoc, double x, double y)
+   Draws a line */
+void php3_pdf_lineto(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &arg1, &arg2, &arg3) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_lineto(pdf, (float) arg2->value.dval, (float) arg3->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_circle(int pdfdoc, double x, double y, double radius)
+   Draws a circle */
+void php3_pdf_circle(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       convert_to_double(arg4);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_circle(pdf, (float) arg2->value.dval, (float) arg3->value.dval, (float) arg4->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_arc(int pdfdoc, double x, double y, double radius, double start, double end)
+   Draws an arc */
+void php3_pdf_arc(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 6 || getParameters(ht, 6, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       convert_to_double(arg4);
+       convert_to_double(arg5);
+       convert_to_double(arg6);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_arc(pdf, (float) arg2->value.dval, (float) arg3->value.dval, (float) arg4->value.dval, (float) arg5->value.dval, (float) arg6->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_rect(int pdfdoc, double x, double y, double width, double height)
+   Draws a rectangle */
+void php3_pdf_rect(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4, *arg5;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 5 || getParameters(ht, 5, &arg1, &arg2, &arg3, &arg4, &arg5) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       convert_to_double(arg3);
+       convert_to_double(arg4);
+       convert_to_double(arg5);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_rect(pdf, (float) arg2->value.dval,
+                       (float) arg3->value.dval,
+                       (float) arg4->value.dval,
+                       (float) arg5->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_closepath(int pdfdoc)
+   Close path */
+void php3_pdf_closepath(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_closepath(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_closepath_stroke(int pdfdoc)
+   Close path and draw line along path */
+void php3_pdf_closepath_stroke(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_closepath_stroke(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_closepath_stroke(int pdfdoc)
+   Draw line along path path */
+void php3_pdf_stroke(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_stroke(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_fill(int pdfdoc)
+   Fill current path */
+void php3_pdf_fill(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_fill(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_fill_stroke(int pdfdoc)
+   Fill and stroke current path */
+void php3_pdf_fill_stroke(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_fill_stroke(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_closepath_fill_stroke(int pdfdoc)
+   Close, fill and stroke current path */
+void php3_pdf_closepath_fill_stroke(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_closepath_fill_stroke(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_endpath(int pdfdoc)
+   Ends current path */
+void php3_pdf_endpath(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_endpath(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_clip(int pdfdoc)
+   Clips to current path */
+void php3_pdf_clip(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_clip(pdf);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setgray_fill(int pdfdoc, double value)
+   Sets filling color to gray value */
+void php3_pdf_setgray_fill(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_setgray_fill(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setgray_stroke(int pdfdoc, double value)
+   Sets drawing color to gray value */
+void php3_pdf_setgray_stroke(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_setgray_stroke(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setgray(int pdfdoc, double value)
+   Sets drawing and filling color to gray value */
+void php3_pdf_setgray(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_setgray(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setrgbcolor_fill(int pdfdoc, double red, double green, double blue)
+   Sets filling color to rgb color value */
+void php3_pdf_setrgbcolor_fill(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_setrgbcolor_fill(pdf, (float) arg2->value.dval, (float) arg3->value.dval, (float) arg4->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setrgbcolor_stroke(int pdfdoc, double red, double green, double blue)
+   Sets drawing color to rgb color value */
+void php3_pdf_setrgbcolor_stroke(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_setrgbcolor_stroke(pdf, (float) arg2->value.dval, (float) arg3->value.dval, (float) arg4->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_setrgbcolor(int pdfdoc, double red, double green, double blue)
+   Sets drawing and filling color to rgb color value */
+void php3_pdf_setrgbcolor(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3, *arg4;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 4 || getParameters(ht, 4, &arg1, &arg2, &arg3, &arg4) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_setrgbcolor(pdf, (float) arg2->value.dval, (float) arg3->value.dval, (float) arg4->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_add_outline(int pdfdoc, string text);
+   Add bookmark for current page */
+void php3_pdf_add_outline(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_string(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_add_outline(pdf, arg2->value.str.val);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_transition(int pdfdoc, int transition)
+   Sets transition between pages */
+void php3_pdf_set_transition(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_long(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_set_transition(pdf, arg2->value.lval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto void pdf_set_duration(int pdfdoc, double duration)
+   Sets duration between pages */
+void php3_pdf_set_duration(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int id, type;
+       PDF *pdf;
+       PDF_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(arg1);
+       convert_to_double(arg2);
+       id=arg1->value.lval;
+       pdf = php3_list_find(id,&type);
+       if(!pdf || type!=PDF_GLOBAL(le_pdf)) {
+               php3_error(E_WARNING,"Unable to find file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       PDF_set_duration(pdf, (float) arg2->value.dval);
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/pdf/php3_pdf.h b/ext/pdf/php3_pdf.h
new file mode 100644 (file)
index 0000000..2f97e60
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Uwe Steinmann                                               |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+#ifndef _PHP3_PDF_H
+#define _PHP3_PDF_H
+
+#if HAVE_PDFLIB
+
+#include <pdf.h>
+
+extern int le_fp;
+
+extern php3_module_entry pdf_module_entry;
+#define pdf_module_ptr &pdf_module_entry
+
+extern void php3_info_pdf(void);
+extern int php3_minit_pdf(INIT_FUNC_ARGS);
+extern int php3_mend_pdf(void);
+extern void php3_pdf_get_info(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_info_creator(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_info_title(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_info_subject(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_info_author(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_info_keywords(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_open(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_close(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_begin_page(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_end_page(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_show(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_show_xy(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_font(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_leading(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_text_rendering(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_horiz_scaling(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_text_rise(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_text_matrix(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_text_pos(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_char_spacing(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_word_spacing(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_continue_text(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_stringwidth(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_save(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_restore(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_translate(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_scale(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_rotate(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setflat(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setlinejoin(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setlinecap(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setmiterlimit(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setlinewidth(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setdash(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_moveto(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_curveto(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_lineto(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_circle(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_arc(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_rect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_closepath(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_closepath_stroke(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_stroke(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_fill(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_fill_stroke(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_closepath_fill_stroke(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_endpath(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_clip(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setgray_fill(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setgray_stroke(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setgray(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setrgbcolor_fill(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setrgbcolor_stroke(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_setrgbcolor(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_add_outline(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_transition(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pdf_set_duration(INTERNAL_FUNCTION_PARAMETERS);
+#else
+#define pdf_module_ptr NULL
+#endif
+#endif /* _PHP3_PDF_H */
diff --git a/ext/pdf/setup.stub b/ext/pdf/setup.stub
new file mode 100644 (file)
index 0000000..a6df9c6
--- /dev/null
@@ -0,0 +1,7 @@
+# $Source$
+# $Id$
+
+define_option with-pdflib 'pdflib 0.6 support? ' yesnodir \
+    'no /usr/local pdflib install' \
+'    Whether to use the pdflib support to write .pdf-files.\n
+    Tested for version 0.6!'
diff --git a/ext/pgsql/Makefile.am b/ext/pgsql/Makefile.am
new file mode 100644 (file)
index 0000000..fa41b29
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_pgsql.a
+libphpext_pgsql_a_SOURCES=pgsql.c
+
diff --git a/ext/pgsql/config.h.stub b/ext/pgsql/config.h.stub
new file mode 100644 (file)
index 0000000..fa21acc
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef HAVE_PGSQL
+#define HAVE_PGSQL 0
+#endif
+
+#ifndef HAVE_PQCMDTUPLES
+#define HAVE_PQCMDTUPLES 0
+#endif
+
diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4
new file mode 100644 (file)
index 0000000..22aa33c
--- /dev/null
@@ -0,0 +1,38 @@
+dnl $Id$
+
+AC_MSG_CHECKING(for PostgresSQL support)
+AC_ARG_WITH(pgsql,
+[  --with-pgsql[=DIR]      Include PostgresSQL support.  DIR is the PostgresSQL
+                          base install directory, defaults to /usr/local/pgsql.],
+[
+  if test "$withval" != "no"; then
+    if test "$withval" = "yes"; then
+      PGSQL_INCDIR=/usr/local/pgsql/include
+      PGSQL_LIBDIR=/usr/local/pgsql/lib
+    else
+      PGSQL_INCDIR=$withval/include
+      test -d $withval/include/pgsql && PGSQL_INCDIR=$withval/include/pgsql
+      PGSQL_LIBDIR=$withval/lib
+      test -d $withval/lib/pgsql && PGSQL_LIBDIR=$withval/lib/pgsql
+    fi
+    PGSQL_INCLUDE=-I$PGSQL_INCDIR
+    PGSQL_LFLAGS=-L$PGSQL_LIBDIR
+    PGSQL_LIBS=-lpq
+
+    old_CFLAGS=$CFLAGS; old_LDFLAGS=$LDFLAGS; old_LIBS=$LIBS
+    CFLAGS="$CFLAGS $PGSQL_INCLUDE"
+    LDFLAGS="$LDFLAGS $PGSQL_LFLAGS"
+    LIBS="$LIBS $PGSQL_LIBS"
+    AC_DEFINE(HAVE_PGSQL)
+    AC_MSG_RESULT(yes)
+    AC_CHECK_FUNC(PQcmdTuples,AC_DEFINE(HAVE_PQCMDTUPLES))
+    CFLAGS=$old_CFLAGS; LDFLAGS=$old_LDFLAGS; LIBS=$old_LIBS
+    PHP_EXTENSION(pgsql)
+    EXTRA_LIBS="$EXTRA_LIBS $PGSQL_LFLAGS $PGSQL_LIBS"
+    INCLUDES="$INCLUDES $PGSQL_INCLUDE"
+  else
+    AC_MSG_RESULT(no)
+  fi
+],[
+  AC_MSG_RESULT(no)
+])
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
new file mode 100644 (file)
index 0000000..fa38715
--- /dev/null
@@ -0,0 +1,1490 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Zeev Suraski <zeev@zend.com>                                |
+   |          Jouni Ahto <jah@cultnet.fi> (large object interface)        |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+#include <stdlib.h>
+
+#ifndef MSVC5
+#include "config.h"
+#endif
+#include "php.h"
+#include "php3_pgsql.h"
+#include "ext/standard/php3_standard.h"
+#include "php_globals.h"
+
+#if HAVE_PGSQL
+
+
+
+function_entry pgsql_functions[] = {
+       {"pg_connect",          php3_pgsql_connect,                     NULL},
+       {"pg_pconnect",         php3_pgsql_pconnect,            NULL},
+       {"pg_close",            php3_pgsql_close,                       NULL},
+       {"pg_cmdtuples",        php3_pgsql_cmdtuples,           NULL},
+       {"pg_dbname",           php3_pgsql_dbname,                      NULL},
+       {"pg_errormessage",     php3_pgsql_error_message,       NULL},
+       {"pg_options",          php3_pgsql_options,                     NULL},
+       {"pg_port",                     php3_pgsql_port,                        NULL},
+       {"pg_tty",                      php3_pgsql_tty,                         NULL},
+       {"pg_host",                     php3_pgsql_host,                        NULL},
+       {"pg_exec",                     php3_pgsql_exec,                        NULL},
+       {"pg_numrows",          php3_pgsql_num_rows,            NULL},
+       {"pg_numfields",        php3_pgsql_num_fields,          NULL},
+       {"pg_fieldname",        php3_pgsql_field_name,          NULL},
+       {"pg_fieldsize",        php3_pgsql_field_size,          NULL},
+       {"pg_fieldtype",        php3_pgsql_field_type,          NULL},
+       {"pg_fieldnum",         php3_pgsql_field_number,        NULL},
+       {"pg_result",           php3_pgsql_result,                      NULL},
+       {"pg_fetch_row",        php3_pgsql_fetch_row,           NULL},
+       {"pg_fetch_array",      php3_pgsql_fetch_array,         NULL},
+       {"pg_fetch_object",     php3_pgsql_fetch_object,        NULL},
+       {"pg_fieldprtlen",      php3_pgsql_data_length,         NULL},
+       {"pg_fieldisnull",      php3_pgsql_data_isnull,         NULL},
+       {"pg_freeresult",       php3_pgsql_free_result,         NULL},
+       {"pg_getlastoid",       php3_pgsql_last_oid,            NULL},
+       {"pg_locreate",         php3_pgsql_lo_create,           NULL},
+       {"pg_lounlink",         php3_pgsql_lo_unlink,           NULL},
+       {"pg_loopen",           php3_pgsql_lo_open,                     NULL},
+       {"pg_loclose",          php3_pgsql_lo_close,            NULL},
+       {"pg_loread",           php3_pgsql_lo_read,                     NULL},
+       {"pg_lowrite",          php3_pgsql_lo_write,            NULL},
+       {"pg_loreadall",        php3_pgsql_lo_readall,          NULL},
+       {NULL, NULL, NULL}
+};
+
+php3_module_entry pgsql_module_entry = {
+       "PostgreSQL", pgsql_functions, php3_minit_pgsql, NULL, php3_rinit_pgsql, NULL, NULL, STANDARD_MODULE_PROPERTIES
+};
+
+#if COMPILE_DL
+php3_module_entry *get_module() { return &pgsql_module_entry; }
+#endif
+
+THREAD_LS pgsql_module php3_pgsql_module;
+
+static void _close_pgsql_link(PGconn *link)
+{
+       PQfinish(link);
+       php3_pgsql_module.num_links--;
+}
+
+
+static void _close_pgsql_plink(PGconn *link)
+{
+       PQfinish(link);
+       php3_pgsql_module.num_persistent--;
+       php3_pgsql_module.num_links--;
+}
+
+
+static void _free_ptr(pgLofp *lofp)
+{
+       efree(lofp);
+}
+
+
+static void _free_result(pgsql_result_handle *pg_result)
+{
+       PQclear(pg_result->result);
+       efree(pg_result);
+}
+
+
+int php3_minit_pgsql(INIT_FUNC_ARGS)
+{
+       if (cfg_get_long("pgsql.allow_persistent",&php3_pgsql_module.allow_persistent)==FAILURE) {
+               php3_pgsql_module.allow_persistent=1;
+       }
+       if (cfg_get_long("pgsql.max_persistent",&php3_pgsql_module.max_persistent)==FAILURE) {
+               php3_pgsql_module.max_persistent=-1;
+       }
+       if (cfg_get_long("pgsql.max_links",&php3_pgsql_module.max_links)==FAILURE) {
+               php3_pgsql_module.max_links=-1;
+       }
+       php3_pgsql_module.num_persistent=0;
+       php3_pgsql_module.le_link = register_list_destructors(_close_pgsql_link,NULL);
+       php3_pgsql_module.le_plink = register_list_destructors(NULL,_close_pgsql_plink);
+       /*      php3_pgsql_module.le_result = register_list_destructors(PQclear,NULL); */
+       php3_pgsql_module.le_result = register_list_destructors(_free_result,NULL);
+       php3_pgsql_module.le_lofp = register_list_destructors(_free_ptr,NULL);
+       php3_pgsql_module.le_string = register_list_destructors(_free_ptr,NULL);
+       return SUCCESS;
+}
+
+
+int php3_rinit_pgsql(INIT_FUNC_ARGS)
+{
+       php3_pgsql_module.default_link=-1;
+       php3_pgsql_module.num_links = php3_pgsql_module.num_persistent;
+       return SUCCESS;
+}
+
+
+void php3_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent)
+{
+       char *host=NULL,*port=NULL,*options=NULL,*tty=NULL,*dbname=NULL,*connstring=NULL;
+       char *hashed_details;
+       int hashed_details_length;
+       PGconn *pgsql;
+       
+       switch(ARG_COUNT(ht)) {
+               case 1: { /* new style, using connection string */
+                               pval *yyconnstring;
+                               if (getParameters(ht, 1, &yyconnstring) == FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyconnstring);
+                               connstring = yyconnstring->value.str.val;
+                               hashed_details_length = yyconnstring->value.str.len+5+1;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"pgsql_%s",connstring); /* SAFE */
+                       }
+                       break;
+               case 3: { /* host, port, dbname */
+                               pval *yyhost, *yyport, *yydbname;
+                               
+                               if (getParameters(ht, 3, &yyhost, &yyport, &yydbname) == FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               convert_to_string(yyport);
+                               convert_to_string(yydbname);
+                               host = yyhost->value.str.val;
+                               port = yyport->value.str.val;
+                               dbname = yydbname->value.str.val;
+                               options=tty=NULL;
+                               hashed_details_length = yyhost->value.str.len+yyport->value.str.len+yydbname->value.str.len+5+5;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"pgsql_%s_%s___%s",host,port,dbname);  /* SAFE */
+                       }
+                       break;
+               case 4: { /* host, port, options, dbname */
+                               pval *yyhost, *yyport, *yyoptions, *yydbname;
+                               
+                               if (getParameters(ht, 4, &yyhost, &yyport, &yyoptions, &yydbname) == FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               convert_to_string(yyport);
+                               convert_to_string(yyoptions);
+                               convert_to_string(yydbname);
+                               host = yyhost->value.str.val;
+                               port = yyport->value.str.val;
+                               options = yyoptions->value.str.val;
+                               dbname = yydbname->value.str.val;
+                               tty=NULL;
+                               hashed_details_length = yyhost->value.str.len+yyport->value.str.len+yyoptions->value.str.len+yydbname->value.str.len+5+5;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"pgsql_%s_%s_%s__%s",host,port,options,dbname);  /* SAFE */
+                       }
+                       break;
+               case 5: { /* host, port, options, tty, dbname */
+                               pval *yyhost, *yyport, *yyoptions, *yytty, *yydbname;
+                               
+                               if (getParameters(ht, 5, &yyhost, &yyport, &yyoptions, &yytty, &yydbname) == FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               convert_to_string(yyport);
+                               convert_to_string(yyoptions);
+                               convert_to_string(yytty);
+                               convert_to_string(yydbname);
+                               host = yyhost->value.str.val;
+                               port = yyport->value.str.val;
+                               options = yyoptions->value.str.val;
+                               tty = yytty->value.str.val;
+                               dbname = yydbname->value.str.val;
+                               hashed_details_length = yyhost->value.str.len+yyport->value.str.len+yyoptions->value.str.len+yytty->value.str.len+yydbname->value.str.len+5+5;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"pgsql_%s_%s_%s_%s_%s",host,port,options,tty,dbname);  /* SAFE */
+                       }
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       if (persistent) {
+               list_entry *le;
+               
+               /* try to find if we already have this link in our persistent list */
+               if (_php3_hash_find(plist, hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {  /* we don't */
+                       list_entry new_le;
+                       
+                       if (php3_pgsql_module.max_links!=-1 && php3_pgsql_module.num_links>=php3_pgsql_module.max_links) {
+                               php3_error(E_WARNING,"PostgresSQL:  Too many open links (%d)",php3_pgsql_module.num_links);
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       if (php3_pgsql_module.max_persistent!=-1 && php3_pgsql_module.num_persistent>=php3_pgsql_module.max_persistent) {
+                               php3_error(E_WARNING,"PostgresSQL:  Too many open persistent links (%d)",php3_pgsql_module.num_persistent);
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+
+                       /* create the link */
+                       if (connstring) {
+                               pgsql=PQconnectdb(connstring);
+                       } else {
+                               pgsql=PQsetdb(host,port,options,tty,dbname);
+                       }
+                       if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
+                               php3_error(E_WARNING,"Unable to connect to PostgresSQL server:  %s",PQerrorMessage(pgsql));
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+
+                       /* hash it up */
+                       new_le.type = php3_pgsql_module.le_plink;
+                       new_le.ptr = pgsql;
+                       if (_php3_hash_update(plist, hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry), NULL)==FAILURE) {
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       php3_pgsql_module.num_links++;
+                       php3_pgsql_module.num_persistent++;
+               } else {  /* we do */
+                       if (le->type != php3_pgsql_module.le_plink) {
+                               RETURN_FALSE;
+                       }
+                       /* ensure that the link did not die */
+                       if (PQstatus(le->ptr)==CONNECTION_BAD) { /* the link died */
+                               if (connstring) {
+                                       le->ptr=PQconnectdb(connstring);
+                               } else {
+                                       le->ptr=PQsetdb(host,port,options,tty,dbname);
+                               }
+                               if (le->ptr==NULL || PQstatus(le->ptr)==CONNECTION_BAD) {
+                                       php3_error(E_WARNING,"PostgresSQL link lost, unable to reconnect");
+                                       _php3_hash_del(plist,hashed_details,hashed_details_length+1);
+                                       efree(hashed_details);
+                                       RETURN_FALSE;
+                               }
+                       }
+                       pgsql = (PGconn *) le->ptr;
+               }
+               return_value->value.lval = php3_list_insert(pgsql,php3_pgsql_module.le_plink);
+               return_value->type = IS_LONG;
+       } else {
+               list_entry *index_ptr,new_index_ptr;
+               
+               /* first we check the hash for the hashed_details key.  if it exists,
+                * it should point us to the right offset where the actual pgsql link sits.
+                * if it doesn't, open a new pgsql link, add it to the resource list,
+                * and add a pointer to it with hashed_details as the key.
+                */
+               if (_php3_hash_find(list,hashed_details,hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
+                       int type,link;
+                       void *ptr;
+
+                       if (index_ptr->type != le_index_ptr) {
+                               RETURN_FALSE;
+                       }
+                       link = (int) index_ptr->ptr;
+                       ptr = php3_list_find(link,&type);   /* check if the link is still there */
+                       if (ptr && (type==php3_pgsql_module.le_link || type==php3_pgsql_module.le_plink)) {
+                               return_value->value.lval = php3_pgsql_module.default_link = link;
+                               return_value->type = IS_LONG;
+                               efree(hashed_details);
+                               return;
+                       } else {
+                               _php3_hash_del(list,hashed_details,hashed_details_length+1);
+                       }
+               }
+               if (php3_pgsql_module.max_links!=-1 && php3_pgsql_module.num_links>=php3_pgsql_module.max_links) {
+                       php3_error(E_WARNING,"PostgresSQL:  Too many open links (%d)",php3_pgsql_module.num_links);
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+               if (connstring) {
+                       pgsql=PQconnectdb(connstring);
+               } else {
+                       pgsql=PQsetdb(host,port,options,tty,dbname);
+               }
+               if (pgsql==NULL || PQstatus(pgsql)==CONNECTION_BAD) {
+                       php3_error(E_WARNING,"Unable to connect to PostgresSQL server:  %s",PQerrorMessage(pgsql));
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+
+               /* add it to the list */
+               return_value->value.lval = php3_list_insert(pgsql,php3_pgsql_module.le_link);
+               return_value->type = IS_LONG;
+
+               /* add it to the hash */
+               new_index_ptr.ptr = (void *) return_value->value.lval;
+               new_index_ptr.type = le_index_ptr;
+               if (_php3_hash_update(list,hashed_details,hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry), NULL)==FAILURE) {
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+               php3_pgsql_module.num_links++;
+       }
+       efree(hashed_details);
+       php3_pgsql_module.default_link=return_value->value.lval;
+}
+
+
+int php3_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
+{
+       if (php3_pgsql_module.default_link==-1) { /* no link opened yet, implicitly open one */
+               HashTable tmp;
+               
+               _php3_hash_init(&tmp,0,NULL,NULL,0);
+               php3_pgsql_do_connect(&tmp,return_value,list,plist,0);
+               _php3_hash_destroy(&tmp);
+       }
+       return php3_pgsql_module.default_link;
+}
+
+/* {{{ proto int pg_connect([string connection_string] | [string host, string port, [string options, [string tty,]] string database)
+   Open a PostgreSQL connection */
+void php3_pgsql_connect(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
+}
+/* }}} */
+
+/* {{{ proto int pg_connect([string connection_string] | [string host, string port, [string options, [string tty,]] string database)
+   Open a persistent PostgreSQL connection */
+void php3_pgsql_pconnect(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
+/* }}} */
+
+/* {{{ proto bool pg_close([int connection])
+   Close a PostgreSQL connection */ 
+void php3_pgsql_close(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pgsql_link;
+       int id,type;
+       PGconn *pgsql;
+       
+       switch (ARG_COUNT(ht)) {
+               case 0:
+                       id = php3_pgsql_module.default_link;
+                       break;
+               case 1:
+                       if (getParameters(ht, 1, &pgsql_link)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_link);
+                       id = pgsql_link->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       pgsql = (PGconn *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_link && type!=php3_pgsql_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL link index",id);
+               RETURN_FALSE;
+       }
+       
+       php3_list_delete(pgsql_link->value.lval);
+       RETURN_TRUE;
+}
+/* }}} */
+
+
+#define PHP3_PG_DBNAME 1
+#define PHP3_PG_ERROR_MESSAGE 2
+#define PHP3_PG_OPTIONS 3
+#define PHP3_PG_PORT 4
+#define PHP3_PG_TTY 5
+#define PHP3_PG_HOST 6
+
+void php3_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
+{
+       pval *pgsql_link;
+       int id,type;
+       PGconn *pgsql;
+       
+       switch(ARG_COUNT(ht)) {
+               case 0:
+                       id = php3_pgsql_module.default_link;
+                       break;
+               case 1:
+                       if (getParameters(ht, 1, &pgsql_link)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_link);
+                       id = pgsql_link->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       pgsql = (PGconn *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_link && type!=php3_pgsql_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL link index",id);
+               RETURN_FALSE;
+       }
+       
+       switch(entry_type) {
+               case PHP3_PG_DBNAME:
+                       return_value->value.str.val = PQdb(pgsql);
+                       break;
+               case PHP3_PG_ERROR_MESSAGE:
+                       return_value->value.str.val = PQerrorMessage(pgsql);
+                       break;
+               case PHP3_PG_OPTIONS:
+                       return_value->value.str.val = PQoptions(pgsql);
+                       break;
+               case PHP3_PG_PORT:
+                       return_value->value.str.val = PQport(pgsql);
+                       break;
+               case PHP3_PG_TTY:
+                       return_value->value.str.val = PQtty(pgsql);
+                       break;
+               case PHP3_PG_HOST:
+                       return_value->value.str.val = PQhost(pgsql);
+                       break;
+               default:
+                       RETURN_FALSE;
+       }
+       return_value->value.str.len = strlen(return_value->value.str.val);
+       return_value->value.str.val = (char *) estrdup(return_value->value.str.val);
+       return_value->type = IS_STRING;
+}
+
+/* {{{ proto string pg_dbname([int connection])
+   Get the database name */ 
+void php3_pgsql_dbname(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_DBNAME);
+}
+/* }}} */
+
+/* {{{ proto string pg_errormessage([int connection])
+   Get the error message string */
+void php3_pgsql_error_message(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_ERROR_MESSAGE);
+}
+/* }}} */
+
+/* {{{ proto string pg_options([int connection])
+   Get the options associated with the connection */
+void php3_pgsql_options(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_OPTIONS);
+}
+/* }}} */
+
+/* {{{ proto int pg_port([int connection])
+   Return the port number associated with the connection */
+void php3_pgsql_port(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_PORT);
+}
+/* }}} */
+
+/* {{{ proto string pg_tty([int connection])
+   Return the tty name associated with the connection */
+void php3_pgsql_tty(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_TTY);
+}
+/* }}} */
+
+/* {{{ proto string pg_host([int connection])
+   Returns the host name associated with the connection */
+void php3_pgsql_host(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_link_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_HOST);
+}
+/* }}} */
+
+/* {{{ proto int pg_exec([int connection,] string query)
+   Execute a query */
+void php3_pgsql_exec(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *query,*pgsql_link;
+       int id,type;
+       PGconn *pgsql;
+       PGresult *pgsql_result;
+       ExecStatusType  status;
+       pgsql_result_handle *pg_result;
+       
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &query)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       id = php3_pgsql_module.default_link;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &pgsql_link, &query)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_link);
+                       id = pgsql_link->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       pgsql = (PGconn *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_link && type!=php3_pgsql_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL link index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_string(query);
+       pgsql_result=PQexec(pgsql,query->value.str.val);
+       
+       if (pgsql_result) {
+               status = PQresultStatus(pgsql_result);
+       } else {
+               status = (ExecStatusType) PQstatus(pgsql);
+       }
+       
+       
+       switch (status) {
+               case PGRES_EMPTY_QUERY:
+               case PGRES_BAD_RESPONSE:
+               case PGRES_NONFATAL_ERROR:
+               case PGRES_FATAL_ERROR:
+                       php3_error(E_WARNING,"PostgresSQL query failed:  %s",PQerrorMessage(pgsql));
+                       RETURN_FALSE;
+                       break;
+               case PGRES_COMMAND_OK: /* successful command that did not return rows */
+               default:
+                       if (pgsql_result) {
+                               pg_result = (pgsql_result_handle *) emalloc(sizeof(pgsql_result_handle));
+                               pg_result->conn = pgsql;
+                               pg_result->result = pgsql_result;
+                               return_value->value.lval = php3_list_insert(pg_result,php3_pgsql_module.le_result);
+                               return_value->type = IS_LONG;
+                       } else {
+                               RETURN_FALSE;
+                       }
+                       break;
+       }
+}
+/* }}} */
+
+#define PHP3_PG_NUM_ROWS 1
+#define PHP3_PG_NUM_FIELDS 2
+#define PHP3_PG_CMD_TUPLES 3
+
+void php3_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
+{
+       pval *result;
+       PGresult *pgsql_result;
+       pgsql_result_handle *pg_result;
+       int type;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       
+       pgsql_result = pg_result->result;
+       
+       switch (entry_type) {
+               case PHP3_PG_NUM_ROWS:
+                       return_value->value.lval = PQntuples(pgsql_result);
+                       break;
+               case PHP3_PG_NUM_FIELDS:
+                       return_value->value.lval = PQnfields(pgsql_result);
+                       break;
+               case PHP3_PG_CMD_TUPLES:
+#if HAVE_PQCMDTUPLES
+                       return_value->value.lval = atoi(PQcmdTuples(pgsql_result));
+#else
+                       php3_error(E_WARNING,"This compilation does not support pg_cmdtuples()");
+                       return_value->value.lval = 0;
+#endif
+                       break;
+               default:
+                       RETURN_FALSE;
+       }
+       return_value->type = IS_LONG;
+}
+
+/* {{{ proto int pg_numrows(int result)
+   Return the number of rows in the result */
+void php3_pgsql_num_rows(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_NUM_ROWS);
+}
+/* }}} */
+
+/* {{{ proto int pg_numfields(int result)
+   Return the number of fields in the result */
+void php3_pgsql_num_fields(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_NUM_FIELDS);
+}
+/* }}} */
+
+/* {{{ proto int pg_cmdtuples(int result)
+   Returns the number of affected tuples */
+void php3_pgsql_cmdtuples(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_result_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_CMD_TUPLES);
+}
+/* }}} */
+
+
+char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list)
+{
+       PGresult *result;
+       char hashed_oid_key[32];
+       list_entry *field_type;
+       char *ret=NULL;
+       
+       /* try to lookup the type in the resource list */
+       snprintf(hashed_oid_key,31,"pgsql_oid_%d",(int) oid);
+       hashed_oid_key[31]=0;
+
+       if (_php3_hash_find(list,hashed_oid_key,strlen(hashed_oid_key)+1,(void **) &field_type)==SUCCESS) {
+               ret = estrdup((char *)field_type->ptr);
+       } else { /* hash all oid's */
+               int i,num_rows;
+               int oid_offset,name_offset;
+               char *tmp_oid, *tmp_name;
+               list_entry new_oid_entry;
+
+               if ((result=PQexec(pgsql,"select oid,typname from pg_type"))==NULL) {
+                       return empty_string;
+               }
+               num_rows=PQntuples(result);
+               oid_offset = PQfnumber(result,"oid");
+               name_offset = PQfnumber(result,"typname");
+               
+               for (i=0; i<num_rows; i++) {
+                       if ((tmp_oid=PQgetvalue(result,i,oid_offset))==NULL) {
+                               continue;
+                       }
+                       snprintf(hashed_oid_key,31,"pgsql_oid_%s",tmp_oid);
+                       if ((tmp_name=PQgetvalue(result,i,name_offset))==NULL) {
+                               continue;
+                       }
+                       new_oid_entry.type = php3_pgsql_module.le_string;
+                       new_oid_entry.ptr = estrdup(tmp_name);
+                       _php3_hash_update(list,hashed_oid_key,strlen(hashed_oid_key)+1,(void *) &new_oid_entry, sizeof(list_entry), NULL);
+                       if (!ret && atoi(tmp_oid)==oid) {
+                               ret = estrdup(tmp_name);
+                       }
+               }
+       }
+       return ret;
+}
+                       
+
+#define PHP3_PG_FIELD_NAME 1
+#define PHP3_PG_FIELD_SIZE 2
+#define PHP3_PG_FIELD_TYPE 3
+
+void php3_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
+{
+       pval *result,*field;
+       PGresult *pgsql_result;
+       pgsql_result_handle *pg_result;
+       int type;
+       
+       if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &result, &field)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       
+       pgsql_result = pg_result->result;
+       convert_to_long(field);
+       
+       if (field->value.lval<0 || field->value.lval>=PQnfields(pgsql_result)) {
+               php3_error(E_WARNING,"Bad field offset specified");
+               RETURN_FALSE;
+       }
+       
+       switch (entry_type) {
+               case PHP3_PG_FIELD_NAME:
+                       return_value->value.str.val = PQfname(pgsql_result,field->value.lval);
+                       return_value->value.str.len = strlen(return_value->value.str.val);
+                       return_value->value.str.val = estrndup(return_value->value.str.val,return_value->value.str.len);
+                       return_value->type = IS_STRING;
+                       break;
+               case PHP3_PG_FIELD_SIZE:
+                       return_value->value.lval = PQfsize(pgsql_result,field->value.lval);
+                       return_value->type = IS_LONG;
+                       break;
+               case PHP3_PG_FIELD_TYPE:
+                       return_value->value.str.val = get_field_name(pg_result->conn,PQftype(pgsql_result,field->value.lval),list);
+                       return_value->value.str.len = strlen(return_value->value.str.val);
+                       return_value->type = IS_STRING;
+                       break;
+               default:
+                       RETURN_FALSE;
+       }
+}
+
+/* {{{ proto string pg_fieldname(int result, int field_number)
+   Returns the name of the field */
+void php3_pgsql_field_name(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_FIELD_NAME);
+}
+/* }}} */
+
+/* {{{ proto pg_fieldsize(int result, int field_number)
+   Returns the internal size of the field */ 
+void php3_pgsql_field_size(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_FIELD_SIZE);
+}
+/* }}} */
+
+/* {{{ proto string pg_fieldtype(int result, int field_number)
+   Returns the type name for the given field */
+void php3_pgsql_field_type(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_get_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU,PHP3_PG_FIELD_TYPE);
+}
+/* }}} */
+
+/* {{{ proto int pg_fieldnum(int result, string field_name)
+   Returns the field number of the named field */
+void php3_pgsql_field_number(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result,*field;
+       PGresult *pgsql_result;
+       pgsql_result_handle *pg_result;
+       int type;
+       
+       if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &result, &field)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       pgsql_result = pg_result->result;
+       
+       convert_to_string(field);
+       return_value->value.lval = PQfnumber(pgsql_result,field->value.str.val);
+       return_value->type = IS_LONG;
+}
+/* }}} */
+
+/* {{{ proto mixed pg_result(int result, int row_number, mixed field_name)
+   Returns values from a result identifier */
+void php3_pgsql_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result, *row, *field=NULL;
+       PGresult *pgsql_result;
+       pgsql_result_handle *pg_result;
+       int type,field_offset;
+       
+       
+       if (ARG_COUNT(ht)!=3 || getParameters(ht, 3, &result, &row, &field)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       pgsql_result = pg_result->result;
+       
+       convert_to_long(row);
+       if (row->value.lval<0 || row->value.lval>=PQntuples(pgsql_result)) {
+               php3_error(E_WARNING,"Unable to jump to row %d on PostgresSQL result index %d",row->value.lval,result->value.lval);
+               RETURN_FALSE;
+       }
+       switch(field->type) {
+               case IS_STRING:
+                       field_offset = PQfnumber(pgsql_result,field->value.str.val);
+                       break;
+               default:
+                       convert_to_long(field);
+                       field_offset = field->value.lval;
+                       break;
+       }
+       if (field_offset<0 || field_offset>=PQnfields(pgsql_result)) {
+               php3_error(E_WARNING,"Bad column offset specified");
+               RETURN_FALSE;
+       }
+       
+       return_value->value.str.val = PQgetvalue(pgsql_result,row->value.lval,field_offset);
+       return_value->value.str.len = (return_value->value.str.val ? strlen(return_value->value.str.val) : 0);
+       return_value->value.str.val = safe_estrndup(return_value->value.str.val,return_value->value.str.len);
+       return_value->type = IS_STRING;
+}
+/* }}} */
+
+/* {{{ proto array pg_fetchrow(int result, int row)
+   Get a row as an enumerated array */ 
+void php3_pgsql_fetch_row(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result, *row;
+       PGresult *pgsql_result;
+       pgsql_result_handle *pg_result;
+       int type;
+       int i,num_fields;
+       char *element;
+       uint element_len;
+       PLS_FETCH();
+       
+       
+       if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &result, &row)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       pgsql_result = pg_result->result;
+       
+       convert_to_long(row);
+       if (row->value.lval<0 || row->value.lval>=PQntuples(pgsql_result)) {
+               php3_error(E_WARNING,"Unable to jump to row %d on PostgresSQL result index %d",row->value.lval,result->value.lval);
+               RETURN_FALSE;
+       }
+       array_init(return_value);
+       for (i=0,num_fields=PQnfields(pgsql_result); i<num_fields; i++) {
+               element = PQgetvalue(pgsql_result,row->value.lval,i);
+               element_len = (element ? strlen(element) : 0);
+               element = safe_estrndup(element,element_len);
+        if (element) {
+            if (PG(magic_quotes_runtime)) {
+                char *tmp=_php3_addslashes(element,element_len,&element_len,0);
+
+                add_index_stringl(return_value, i, tmp, element_len, 0);
+            } else {
+                add_index_stringl(return_value, i, element, element_len, 1);
+            }
+        } else {
+            /* NULL field, don't set it */
+            /*add_index_stringl(return_value, i, empty_string, 0, 1);*/
+        }
+       }
+}
+/* }}} */
+
+void php3_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result, *row, *pval_ptr;
+       PGresult *pgsql_result;
+       pgsql_result_handle *pg_result;
+       int type;
+       int i,num_fields;
+       char *element,*field_name;
+       uint element_len;
+       PLS_FETCH();
+       
+       
+       if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &result, &row)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       pgsql_result = pg_result->result;
+       
+       convert_to_long(row);
+       if (row->value.lval<0 || row->value.lval>=PQntuples(pgsql_result)) {
+               php3_error(E_WARNING,"Unable to jump to row %d on PostgresSQL result index %d",row->value.lval,result->value.lval);
+               RETURN_FALSE;
+       }
+       array_init(return_value);
+       for (i=0,num_fields=PQnfields(pgsql_result); i<num_fields; i++) {
+               element = PQgetvalue(pgsql_result,row->value.lval,i);
+               element_len = (element ? strlen(element) : 0);
+               element = safe_estrndup(element,element_len);
+               if (element) {
+            if (PG(magic_quotes_runtime)) {
+                char *tmp=_php3_addslashes(element,element_len,&element_len,0);
+
+                add_get_index_stringl(return_value, i, tmp, element_len, (void **) &pval_ptr, 0);
+            } else {
+                add_get_index_stringl(return_value, i, element, element_len, (void **) &pval_ptr, 1);
+            }
+                       field_name = PQfname(pgsql_result,i);
+            _php3_hash_pointer_update(return_value->value.ht, field_name, strlen(field_name)+1, pval_ptr);
+        } else {
+            /* NULL field, don't set it */
+            /* add_get_index_stringl(return_value, i, empty_string, 0, (void **) &pval_ptr); */
+        }
+       }
+}
+
+/* ??  This is a rather odd function - why not just point pg_fetcharray() directly at fetch_hash ? -RL */
+/* {{{ proto array pg_fetch_array(int result, int row)
+   Fetch a row as an array */
+void php3_pgsql_fetch_array(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto object pg_fetch_object(int result, int row)
+   Fetch a row as an object */
+void php3_pgsql_fetch_object(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+       if (return_value->type==IS_ARRAY) {
+               return_value->type = IS_OBJECT;
+       }
+}
+/* }}} */
+
+#define PHP3_PG_DATA_LENGTH 1
+#define PHP3_PG_DATA_ISNULL 2
+
+void php3_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
+{
+       pval *result,*row,*field;
+       PGresult *pgsql_result;
+       pgsql_result_handle *pg_result;
+       int type,field_offset;
+       
+       if (ARG_COUNT(ht)!=3 || getParameters(ht, 3, &result, &row, &field)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       pgsql_result = pg_result->result;
+       
+       convert_to_long(row);
+       if (row->value.lval<0 || row->value.lval>=PQntuples(pgsql_result)) {
+               php3_error(E_WARNING,"Unable to jump to row %d on PostgresSQL result index %d",row->value.lval,result->value.lval);
+               RETURN_FALSE;
+       }
+       switch(field->type) {
+               case IS_STRING:
+                       field_offset = PQfnumber(pgsql_result,field->value.str.val);
+                       break;
+               default:
+                       convert_to_long(field);
+                       field_offset = field->value.lval;
+                       break;
+       }
+       if (field_offset<0 || field_offset>=PQnfields(pgsql_result)) {
+               php3_error(E_WARNING,"Bad column offset specified");
+               RETURN_FALSE;
+       }
+       
+       switch (entry_type) {
+               case PHP3_PG_DATA_LENGTH:
+                       return_value->value.lval = PQgetlength(pgsql_result,row->value.lval,field_offset);
+                       break;
+               case PHP3_PG_DATA_ISNULL:
+                       return_value->value.lval = PQgetisnull(pgsql_result,row->value.lval,field_offset);
+                       break;
+       }
+       return_value->type = IS_LONG;
+}
+
+/* {{{ proto int pg_fieldprtlen(int result, int row, mixed field_name_or_number)
+   Returns the printed length */
+void php3_pgsql_data_length(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_data_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP3_PG_DATA_LENGTH);
+}
+/* }}} */
+
+/* {{{ proto int pg_fieldisnull(int result, int row, mixed field_name_or_number)
+   Test if a field is NULL */
+void php3_pgsql_data_isnull(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_pgsql_data_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP3_PG_DATA_ISNULL);
+}
+/* }}} */
+
+/* {{{ proto int pg_freeresult(int result)
+   Free result memory */
+void php3_pgsql_free_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result;
+       pgsql_result_handle *pg_result;
+       int type;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       if (result->value.lval==0) {
+               RETURN_FALSE;
+       }
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       php3_list_delete(result->value.lval);
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int pg_getlastoid(int result)
+   Returns the last object identifier */
+void php3_pgsql_last_oid(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result;
+       PGresult *pgsql_result;
+       pgsql_result_handle *pg_result;
+       int type;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result);
+       pg_result = (pgsql_result_handle *) php3_list_find(result->value.lval,&type);
+       
+       if (type!=php3_pgsql_module.le_result) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL result index",result->value.lval);
+               RETURN_FALSE;
+       }
+       pgsql_result = pg_result->result;
+       return_value->value.str.val = (char *) PQoidStatus(pgsql_result);
+       if (return_value->value.str.val) {
+               return_value->value.str.len = strlen(return_value->value.str.val);
+               return_value->value.str.val = estrndup(return_value->value.str.val, return_value->value.str.len);
+               return_value->type = IS_STRING;
+       } else {
+               return_value->value.str.val = empty_string;
+       } 
+}
+/* }}} */
+
+/* {{{ proto int pg_locreate(int connection)
+   Create a large object */
+void php3_pgsql_lo_create(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pgsql_link;
+       PGconn *pgsql;
+       Oid pgsql_oid;
+       int id, type;
+       
+       switch(ARG_COUNT(ht)) {
+               case 0:
+                       id = php3_pgsql_module.default_link;
+                       break;
+               case 1:
+                       if (getParameters(ht, 1, &pgsql_link)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_link);
+                       id = pgsql_link->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       pgsql = (PGconn *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_link && type!=php3_pgsql_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL link index",id);
+               RETURN_FALSE;
+       }
+       
+       /* XXX: Archive modes not supported until I get some more data. Don't think anybody's
+          using it anyway. I believe it's also somehow related to the 'time travel' feature of
+          PostgreSQL, that's on the list of features to be removed... Create modes not supported.
+          What's the use of an object that can be only written to, but not read from, and vice
+          versa? Beats me... And the access type (r/w) must be specified again when opening
+          the object, probably (?) overrides this. (Jouni) 
+        */
+
+       if ((pgsql_oid=lo_creat(pgsql, INV_READ|INV_WRITE))==0) {
+               php3_error(E_WARNING,"Unable to create PostgresSQL large object");
+               RETURN_FALSE;
+       }
+
+       return_value->value.lval = pgsql_oid;
+       return_value->type = IS_LONG;
+}
+/* }}} */
+
+/* {{{ proto void pg_lounlink([int connection, ] int large_obj_id)
+   Delete a large object */
+void php3_pgsql_lo_unlink(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pgsql_link, *oid;
+       PGconn *pgsql;
+       Oid pgsql_oid;
+       int id, type;
+
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &oid)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(oid);
+                       pgsql_oid = oid->value.lval;
+                       id = php3_pgsql_module.default_link;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &pgsql_link, &oid)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_link);
+                       id = pgsql_link->value.lval;
+                       convert_to_long(oid);
+                       pgsql_oid = oid->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       pgsql = (PGconn *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_link && type!=php3_pgsql_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL link index",id);
+               RETURN_FALSE;
+       }
+       
+       if (lo_unlink(pgsql, pgsql_oid)==-1) {
+               php3_error(E_WARNING,"Unable to delete PostgresSQL large object %d", (int) pgsql_oid);
+               RETURN_FALSE;
+       }
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int pg_loopen([int connection,] int objoid, string mode)
+   Open a large object and return fd */
+void php3_pgsql_lo_open(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pgsql_link, *oid, *mode;
+       PGconn *pgsql;
+       Oid pgsql_oid;
+       int id, type, pgsql_mode=0, pgsql_lofd;
+       int create=0;
+       char *mode_string=NULL;
+       pgLofp *pgsql_lofp;
+
+       switch(ARG_COUNT(ht)) {
+               case 2:
+                       if (getParameters(ht, 2, &oid, &mode)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(oid);
+                       pgsql_oid = oid->value.lval;
+                       convert_to_string(mode);
+                       mode_string = mode->value.str.val;
+                       id = php3_pgsql_module.default_link;
+                       break;
+               case 3:
+                       if (getParameters(ht, 3, &pgsql_link, &oid, &mode)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_link);
+                       id = pgsql_link->value.lval;
+                       convert_to_long(oid);
+                       pgsql_oid = oid->value.lval;
+                       convert_to_string(mode);
+                       mode_string = mode->value.str.val;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       pgsql = (PGconn *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_link && type!=php3_pgsql_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL link index",id);
+               RETURN_FALSE;
+       }
+       
+       /* r/w/+ is little bit more PHP-like than INV_READ/INV_WRITE and a lot of
+          faster to type. Unfortunately, doesn't behave the same way as fopen()...
+          (Jouni)
+        */
+
+       if (strchr(mode_string, 'r')==mode_string) {
+               pgsql_mode |= INV_READ;
+               if (strchr(mode_string, '+')==mode_string+1) {
+                       pgsql_mode |= INV_WRITE;
+               }
+       }
+       if (strchr(mode_string, 'w')==mode_string) {
+               pgsql_mode |= INV_WRITE;
+               create = 1;
+               if (strchr(mode_string, '+')==mode_string+1) {
+                       pgsql_mode |= INV_READ;
+               }
+       }
+
+
+       pgsql_lofp = (pgLofp *) emalloc(sizeof(pgLofp));
+
+       if ((pgsql_lofd=lo_open(pgsql, pgsql_oid, pgsql_mode))==-1) {
+               if (create) {
+                       if ((pgsql_oid=lo_creat(pgsql, INV_READ|INV_WRITE))==0) {
+                               efree(pgsql_lofp);
+                               php3_error(E_WARNING,"Unable to create PostgresSQL large object");
+                               RETURN_FALSE;
+                       } else {
+                               if ((pgsql_lofd=lo_open(pgsql, pgsql_oid, pgsql_mode))==-1) {
+                                       if (lo_unlink(pgsql, pgsql_oid)==-1) {
+                                               efree(pgsql_lofp);
+                                               php3_error(E_WARNING,"Something's really messed up!!! Your database is badly corrupted in a way NOT related to PHP.");
+                                               RETURN_FALSE;
+                                       }
+                                       efree(pgsql_lofp);
+                                       php3_error(E_WARNING,"Unable to open PostgresSQL large object");
+                                       RETURN_FALSE;
+                               } else {
+                                       pgsql_lofp->conn = pgsql;
+                                       pgsql_lofp->lofd = pgsql_lofd;
+                                       return_value->value.lval = php3_list_insert(pgsql_lofp, php3_pgsql_module.le_lofp);
+                                       return_value->type = IS_LONG;
+                               }
+                       }
+               } else {
+                       efree(pgsql_lofp);
+                       php3_error(E_WARNING,"Unable to open PostgresSQL large object");
+                       RETURN_FALSE;
+               }
+       } else {
+               pgsql_lofp->conn = pgsql;
+               pgsql_lofp->lofd = pgsql_lofd;
+               return_value->value.lval = php3_list_insert(pgsql_lofp, php3_pgsql_module.le_lofp);
+               return_value->type = IS_LONG;
+       }
+}
+/* }}} */
+
+/* {{{ proto void pg_loclose(int fd)
+   Close a large object */
+void php3_pgsql_lo_close(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pgsql_lofp;
+       int id, type;
+       pgLofp *pgsql;
+
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &pgsql_lofp)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_lofp);
+                       id = pgsql_lofp->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       pgsql = (pgLofp *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_lofp) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL large object index",id);
+               RETURN_FALSE;
+       }
+       
+       if (lo_close((PGconn *)pgsql->conn, pgsql->lofd)<0) {
+               php3_error(E_WARNING,"Unable to close PostgresSQL large object descriptor %d", pgsql->lofd);
+               RETVAL_FALSE;
+       } else {
+               RETVAL_TRUE;
+       }
+       php3_list_delete(id);
+       return;
+}
+/* }}} */
+
+/* {{{ proto string pg_loread(int fd, int len)
+   Read a large object */
+void php3_pgsql_lo_read(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pgsql_id, *len;
+       int id, buf_len, type, nbytes;
+       char *buf;
+       pgLofp *pgsql;
+
+       switch(ARG_COUNT(ht)) {
+               case 2:
+                       if (getParameters(ht, 2, &pgsql_id, &len)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_id);
+                       id = pgsql_id->value.lval;
+                       convert_to_long(len);
+                       buf_len = len->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       pgsql = (pgLofp *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_lofp) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL large object index",id);
+               RETURN_FALSE;
+       }
+       
+       buf = (char *) emalloc(sizeof(char)*(buf_len+1));
+       if ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf, buf_len))<0) {
+               efree(buf);
+               RETURN_FALSE;
+       }
+       return_value->value.str.val = buf;
+       return_value->value.str.len = nbytes;
+       return_value->value.str.val[nbytes] = 0;
+       return_value->type = IS_STRING;
+}
+/* }}} */
+
+/* {{{ proto int pg_lowrite(int fd, string buf)
+   Write a large object */
+void php3_pgsql_lo_write(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pgsql_id, *str;
+       int id, buf_len, nbytes, type;
+       char *buf;
+       pgLofp *pgsql;
+
+       switch(ARG_COUNT(ht)) {
+               case 2:
+                       if (getParameters(ht, 2, &pgsql_id, &str)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_id);
+                       id = pgsql_id->value.lval;
+                       convert_to_string(str);
+                       buf = str->value.str.val;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       pgsql = (pgLofp *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_lofp) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL large object index",id);
+               RETURN_FALSE;
+       }
+       
+       buf_len = str->value.str.len;
+       if ((nbytes = lo_write((PGconn *)pgsql->conn, pgsql->lofd, buf, buf_len))==-1) {
+               RETURN_FALSE;
+       }
+       return_value->value.lval = nbytes;
+       return_value->type = IS_LONG;
+}
+/* }}} */
+
+/* {{{ proto void pg_loreadall(int fd)
+   Read a large object and send straight to browser */
+void php3_pgsql_lo_readall(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *pgsql_id;
+       int i, id, tbytes, type;
+       volatile int nbytes;
+       char buf[8192];
+       pgLofp *pgsql;
+       int output=1;
+
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &pgsql_id)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(pgsql_id);
+                       id = pgsql_id->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       pgsql = (pgLofp *) php3_list_find(id,&type);
+       if (type!=php3_pgsql_module.le_lofp) {
+               php3_error(E_WARNING,"%d is not a PostgresSQL large object index",id);
+               RETURN_FALSE;
+       }
+
+       tbytes = 0;
+       while ((nbytes = lo_read((PGconn *)pgsql->conn, pgsql->lofd, buf, 8192))>0) {
+               for(i=0; i<nbytes; i++) {
+                       if (output) PUTC(buf[i]);
+               }
+               tbytes += i;
+       }
+       return_value->value.lval = tbytes;
+       return_value->type = IS_LONG;
+}
+/* }}} */
+       
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/pgsql/php3_pgsql.h b/ext/pgsql/php3_pgsql.h
new file mode 100644 (file)
index 0000000..097e168
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Jouni Ahto                                                  |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+#ifndef _PHP3_PGSQL_H
+#define _PHP3_PGSQL_H
+
+#if COMPILE_DL
+#undef HAVE_PGSQL
+#define HAVE_PGSQL 1
+#endif
+
+#if HAVE_PGSQL
+
+extern php3_module_entry pgsql_module_entry;
+#define pgsql_module_ptr &pgsql_module_entry
+
+
+#include <libpq-fe.h>
+#include <libpq/libpq-fs.h>
+
+extern int php3_minit_pgsql(INIT_FUNC_ARGS);
+extern int php3_rinit_pgsql(INIT_FUNC_ARGS);
+extern void php3_pgsql_connect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_pconnect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_close(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_dbname(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_error_message(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_options(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_port(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_tty(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_host(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_exec(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_num_rows(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_num_fields(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_cmdtuples(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_field_name(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_field_size(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_field_type(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_field_number(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_fetch_row(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_fetch_array(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_fetch_object(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_data_length(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_data_isnull(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_free_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_last_oid(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_lo_create(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_lo_unlink(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_lo_open(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_lo_close(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_lo_read(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_lo_write(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_pgsql_lo_readall(INTERNAL_FUNCTION_PARAMETERS);
+
+void php3_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent);
+int php3_pgsql_get_default_link(INTERNAL_FUNCTION_PARAMETERS);
+void php3_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);
+void php3_pgsql_get_result_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);
+char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list);
+void php3_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);
+void php3_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS);
+void php3_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type);
+
+
+typedef struct pgLofp {
+        PGconn *conn;
+       int lofd;
+} pgLofp;
+
+typedef struct _php3_pgsql_result_handle {
+       PGconn *conn;
+       PGresult *result;
+} pgsql_result_handle;
+
+typedef struct {
+       long default_link;
+       long num_links,num_persistent;
+       long max_links,max_persistent;
+       long allow_persistent;
+       int le_link,le_plink,le_result,le_lofp,le_string;
+} pgsql_module;
+
+extern pgsql_module php3_pgsql_module;
+
+#else
+
+#define pgsql_module_ptr NULL
+
+#endif
+
+#endif /* _PHP3_PGSQL_H */
diff --git a/ext/pgsql/setup.stub b/ext/pgsql/setup.stub
new file mode 100644 (file)
index 0000000..e401946
--- /dev/null
@@ -0,0 +1,8 @@
+# $Source$
+# $Id$
+
+define_option with-pgsql 'PostgreSQL support?' yesnodir \
+    'no /usr/local/pgsql PostgreSQL base install' \
+'    Whether to build PHP with PostgreSQL support.\n
+    More info about PostgreSQL can be found at\n
+    http://www.postgreSQL.org/.'
diff --git a/ext/snmp/Makefile.am b/ext/snmp/Makefile.am
new file mode 100644 (file)
index 0000000..ebb5c25
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_snmp.a
+libphpext_snmp_a_SOURCES=snmp.c
+
diff --git a/ext/snmp/Makefile.in b/ext/snmp/Makefile.in
new file mode 100644 (file)
index 0000000..a010158
--- /dev/null
@@ -0,0 +1,270 @@
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id$
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DISTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+APACHE_INCLUDE = @APACHE_INCLUDE@
+APACHE_TARGET = @APACHE_TARGET@
+APXS = @APXS@
+APXS_LDFLAGS = @APXS_LDFLAGS@
+BINNAME = @BINNAME@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CFLAGS_SHLIB = @CFLAGS_SHLIB@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+EXTINFO_DEPS = @EXTINFO_DEPS@
+EXTRA_LIBS = @EXTRA_LIBS@
+EXT_LIBS = @EXT_LIBS@
+EXT_SUBDIRS = @EXT_SUBDIRS@
+FHTTPD_LIB = @FHTTPD_LIB@
+FHTTPD_TARGET = @FHTTPD_TARGET@
+HSREGEX = @HSREGEX@
+INSTALL_IT = @INSTALL_IT@
+LDFLAGS_SHLIB = @LDFLAGS_SHLIB@
+LDFLAGS_SHLIB_EXPORT = @LDFLAGS_SHLIB_EXPORT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+PERL_PATH = @PERL_PATH@
+PHP_BUILD_DATE = @PHP_BUILD_DATE@
+PHP_DEBUG = @PHP_DEBUG@
+PHP_LIBS = @PHP_LIBS@
+PHP_VERSION = @PHP_VERSION@
+PROG_SENDMAIL = @PROG_SENDMAIL@
+RANLIB = @RANLIB@
+RDYNAMIC_LFLAGS = @RDYNAMIC_LFLAGS@
+REGEX_LIB = @REGEX_LIB@
+STRONGHOLD = @STRONGHOLD@
+VERSION = @VERSION@
+WARNING_LEVEL = @WARNING_LEVEL@
+YACC = @YACC@
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_snmp.a
+libphpext_snmp_a_SOURCES=snmp.c
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libphpext_snmp_a_LIBADD = 
+libphpext_snmp_a_OBJECTS =  snmp.o
+AR = ar
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(libphpext_snmp_a_SOURCES)
+OBJECTS = $(libphpext_snmp_a_OBJECTS)
+
+all: Makefile $(LIBRARIES)
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: @MAINT@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps ext/snmp/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+       $(COMPILE) -c $<
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libphpext_snmp.a: $(libphpext_snmp_a_OBJECTS) $(libphpext_snmp_a_DEPENDENCIES)
+       -rm -f libphpext_snmp.a
+       $(AR) cru libphpext_snmp.a $(libphpext_snmp_a_OBJECTS) $(libphpext_snmp_a_LIBADD)
+       $(RANLIB) libphpext_snmp.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = ext/snmp
+
+distdir: $(DISTFILES)
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
+       done
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
+install-strip:
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f Makefile $(DISTCLEANFILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-generic
+
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
+               mostlyclean
+
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-generic clean
+       -rm -f config.status
+
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-generic distclean
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-exec install-data install uninstall all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ext/snmp/config.h.stub b/ext/snmp/config.h.stub
new file mode 100644 (file)
index 0000000..e400f18
--- /dev/null
@@ -0,0 +1,2 @@
+/* Define if you want the SNMP interface */
+#define HAVE_SNMP 0
diff --git a/ext/snmp/config.m4 b/ext/snmp/config.m4
new file mode 100644 (file)
index 0000000..928dad4
--- /dev/null
@@ -0,0 +1,31 @@
+dnl $Id$
+
+AC_MSG_CHECKING(for SNMP support)
+AC_ARG_WITH(snmp,
+[  --with-snmp[=DIR]       Include SNMP support.  DIR is the SNMP base
+                          install directory, defaults to /usr/local],
+[
+  if test "$withval" != "no"; then
+    if test "$withval" = "yes"; then
+      SNMP_INCDIR=/usr/local/include
+      test -d /usr/local/include/ucd-snmp && SNMP_INCDIR=/usr/local/include/ucd-snmp
+      SNMP_LIBDIR=/usr/local/lib
+    else
+      SNMP_INCDIR=$withval/include
+      test -d $withval/include/ucd-snmp && SNMP_INCDIR=$withval/include/ucd-snmp
+      SNMP_LIBDIR=$withval/lib
+    fi
+    SNMP_INCLUDE=-I$SNMP_INCDIR
+    SNMP_LFLAGS=-L$SNMP_LIBDIR
+    SNMP_LIBS="-lsnmp"
+    AC_DEFINE(HAVE_SNMP)
+    AC_MSG_RESULT(yes)
+    PHP_EXTENSION(snmp)
+    EXTRA_LIBS="$EXTRA_LIBS $SNMP_LFLAGS $SNMP_LIBS"
+    INCLUDES="$INCLUDES $SNMP_INCLUDE"
+  else
+    AC_MSG_RESULT(no)
+  fi
+],[
+  AC_MSG_RESULT(no)
+])
diff --git a/ext/snmp/php3_snmp.h b/ext/snmp/php3_snmp.h
new file mode 100644 (file)
index 0000000..c35962c
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+#ifndef _PHP3_SNMP_H
+#define _PHP3_SNMP_H
+
+#if COMPILE_DL
+#undef HAVE_SNMP
+#define HAVE_SNMP 1
+#endif
+#if HAVE_SNMP
+#ifndef DLEXPORT
+#define DLEXPORT
+#endif
+
+extern php3_module_entry snmp_module_entry;
+#define snmp_module_ptr &snmp_module_entry
+
+extern int php3i_snmp_init(INIT_FUNC_ARGS);
+extern PHP_FUNCTION(snmpget);
+extern PHP_FUNCTION(snmpwalk);
+extern PHP_FUNCTION(snmprealwalk);
+extern void php3_info_snmp(void);
+#else
+
+#define snmp_module_ptr NULL
+
+#endif /* HAVE_SNMP */
+
+#endif  /* _PHP3_SNMP_H */
diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
new file mode 100644 (file)
index 0000000..05c35f3
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+#include "php.h"
+#if defined(COMPILE_DL)
+#include "phpdl.h"
+#include "functions/dl.h"
+#endif
+#include "php3_snmp.h"
+#include <sys/types.h>
+#if MSVC5
+#include <winsock.h>
+#include <errno.h>
+#include <process.h>
+#include "win32/time.h"
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/errno.h>
+#include <netdb.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_SNMP
+
+#ifndef __P
+#ifdef __GNUC__
+#define __P(args) args
+#else
+#define __P(args) ()
+#endif
+#endif
+
+#include "asn1.h"
+#include "snmp_api.h"
+#include "snmp_client.h"
+#include "snmp_impl.h"
+#include "snmp.h"
+#include "parse.h"
+#include "mib.h"
+
+/* ucd-snmp 3.3.1 changed the name of a few #defines... They've been changed back to the original ones in 3.5.3! */
+#ifndef SNMP_MSG_GET
+#define SNMP_MSG_GET GET_REQ_MSG
+#define SNMP_MSG_GETNEXT GETNEXT_REQ_MSG
+#endif
+
+void _php3_snmp(INTERNAL_FUNCTION_PARAMETERS, int st);
+
+/* constant - can be shared among threads */
+static oid objid_mib[] = {1, 3, 6, 1, 2, 1};
+
+/* Add missing prototype */
+void sprint_variable(char *, oid *, int, struct variable_list *);
+
+function_entry snmp_functions[] = {
+       PHP_FE(snmpget, NULL)
+       PHP_FE(snmpwalk, NULL)
+       PHP_FE(snmprealwalk, NULL)
+    {NULL,NULL,NULL}
+};
+
+php3_module_entry snmp_module_entry = {
+       "SNMP",snmp_functions,php3i_snmp_init,NULL,NULL,NULL,php3_info_snmp,STANDARD_MODULE_PROPERTIES
+};
+
+#if COMPILE_DL
+DLEXPORT php3_module_entry *get_module() { return &snmp_module_entry; };
+#endif
+
+/* THREAD_LS snmp_module php3_snmp_module; - may need one of these at some point */
+
+int php3i_snmp_init(INIT_FUNC_ARGS) {
+       init_mib();
+       return SUCCESS;
+}
+
+void php3_info_snmp(void) {
+       php3_printf("ucd-snmp");
+}
+
+
+/*
+ * Generic SNMP object fetcher
+ *
+ * st=1 GET
+ * st=2 WALK
+ * st=3 WALK (returns OIDs additionally)
+ */
+void _php3_snmp(INTERNAL_FUNCTION_PARAMETERS, int st) {
+       pval *a1, *a2, *a3, *a4, *a5;
+       struct snmp_session session, *ss;
+       struct snmp_pdu *pdu=NULL, *response;
+       struct variable_list *vars;
+    char *objid;
+    oid name[MAX_NAME_LEN];
+    int name_length;
+    int status, count,rootlen=0,gotroot=0;
+       oid root[MAX_NAME_LEN];
+       char buf[2048];
+       char buf2[2048];
+       int keepwalking=1;
+       long timeout=SNMP_DEFAULT_TIMEOUT;
+       long retries=SNMP_DEFAULT_RETRIES;
+       int myargc = ARG_COUNT(ht);
+       
+       if (myargc<3 || myargc>5 || getParameters(ht, myargc, &a1, &a2, &a3, &a4, &a5) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_string(a1);
+       convert_to_string(a2);
+       convert_to_string(a3);
+       if(myargc>3) {
+               convert_to_long(a4);
+               timeout=a4->value.lval;
+       }
+       if(myargc>4) {
+               convert_to_long(a5);
+               retries=a5->value.lval;
+       }
+       objid=a3->value.str.val;
+       
+       if (st>=2) { /* walk */
+               rootlen = MAX_NAME_LEN;
+               if (strlen(objid)) { /* on a walk, an empty string means top of tree - no error */
+                       if (read_objid(objid, root, &rootlen)) {
+                               gotroot = 1;
+                       } else {
+                               php3_error(E_WARNING,"Invalid object identifier: %s\n", objid);
+                       }
+               }
+       if (gotroot == 0) {
+                       memmove((char *)root, (char *)objid_mib, sizeof(objid_mib));
+               rootlen = sizeof(objid_mib) / sizeof(oid);
+               gotroot = 1;
+       }
+       }
+
+       memset(&session, 0, sizeof(struct snmp_session));
+       session.peername = a1->value.str.val;
+
+       session.version = SNMP_VERSION_1;
+       /*
+        * FIXME: potential memory leak
+        * This is a workaround for an "artifact" (Mike Slifcak)
+        * in (at least) ucd-snmp 3.6.1 which frees
+        * memory it did not allocate
+        */
+       session.community = (u_char *) strdup(a2->value.str.val);
+       session.community_len = a2->value.str.len;
+       session.retries = retries;
+       session.timeout = timeout;
+
+       session.authenticator = NULL;
+       snmp_synch_setup(&session);
+       ss = snmp_open(&session);
+       if (ss == NULL){
+               php3_error(E_WARNING,"Couldn't open snmp\n");
+               RETURN_FALSE;
+       }
+       if (st>=2) {
+               memmove((char *)name, (char *)root, rootlen * sizeof(oid));
+               name_length = rootlen;
+               /* prepare result array */
+               array_init(return_value);       
+       }
+
+       while(keepwalking) {
+               keepwalking=0;
+               if (st==1) pdu = snmp_pdu_create(SNMP_MSG_GET);
+               else if (st>=2) pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
+
+               if (st==1) {
+                       name_length = MAX_NAME_LEN;
+                       if (!read_objid(objid, name, &name_length)) {
+                               php3_error(E_WARNING,"Invalid object identifier: %s\n", objid);
+                               RETURN_FALSE;
+                       }
+               }
+               snmp_add_null_var(pdu, name, name_length);
+
+retry:
+               status = snmp_synch_response(ss, pdu, &response);
+               if (status == STAT_SUCCESS) {
+                       if (response->errstat == SNMP_ERR_NOERROR) {
+                               for(vars = response->variables; vars; vars = vars->next_variable) {
+                                       if (st>=2 && (vars->name_length < rootlen || memcmp(root, vars->name, rootlen * sizeof(oid))))
+                                               continue;       /* not part of this subtree */
+
+                                       sprint_value(buf,vars->name, vars->name_length, vars);
+#if 0
+                                       Debug("snmp response is: %s\n",buf);
+#endif
+                                       if (st==1) {
+                                               RETVAL_STRING(buf,1);
+                                       } else if (st==2) {
+                                               /* Add to returned array */
+                                               add_next_index_string(return_value,buf,1);
+                                       } else if (st==3) {
+                                               sprint_objid(buf2, name, name_length);
+                                               add_assoc_string(return_value,buf2,buf,1);
+                                       }
+                                       if (st>=2) {
+                                               if (vars->type != SNMP_ENDOFMIBVIEW && vars->type != SNMP_NOSUCHOBJECT && vars->type != SNMP_NOSUCHINSTANCE) {
+                                                       memmove((char *)name, (char *)vars->name,vars->name_length * sizeof(oid));
+                                                       name_length = vars->name_length;
+                                                       keepwalking = 1;
+                                               }
+                                       }
+                               }       
+                       } else {
+                               if (st!=2 || response->errstat != SNMP_ERR_NOSUCHNAME) {
+                                       php3_error(E_WARNING,"Error in packet.\nReason: %s\n", snmp_errstring(response->errstat));
+                                       if (response->errstat == SNMP_ERR_NOSUCHNAME) {
+                                               for(count=1, vars = response->variables; vars && count != response->errindex;
+                                                       vars = vars->next_variable, count++);
+                                               if (vars) sprint_objid(buf,vars->name, vars->name_length);
+                                               php3_error(E_WARNING,"This name does not exist: %s\n",buf);
+                                       }
+                                       if (st==1) {
+                                               if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GET)) != NULL) goto retry;
+                                       } else if (st>=2) {
+                                               if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) != NULL) goto retry;
+                                       }
+                                       RETURN_FALSE;
+                               }
+                       }
+               } else if (status == STAT_TIMEOUT) {
+                       php3_error(E_WARNING,"No Response from %s\n", a1->value.str.val);
+                       RETURN_FALSE;
+               } else {    /* status == STAT_ERROR */
+                       php3_error(E_WARNING,"An error occurred, Quitting\n");
+                       RETURN_FALSE;
+               }
+               if (response) snmp_free_pdu(response);
+       } /* keepwalking */
+       snmp_close(ss);
+}
+
+/* {{{ proto string snmpget(string host, string community, string object_id [, int timeout [, int retries]]) 
+   Fetch an SNMP object */
+void php3_snmpget(INTERNAL_FUNCTION_PARAMETERS) {
+       _php3_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
+/* }}} */
+
+/* {{{ proto string snmpwalk(string host, string community, string object_id [, int timeout [, int retries]]) 
+   Return all objects under the specified object id */
+void php3_snmpwalk(INTERNAL_FUNCTION_PARAMETERS) {
+       return _php3_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,2);
+}
+/* }}} */
+
+/* {{{ proto string snmprealwalk(string host, string community, string object_id [, int timeout [, int retries]])
+   Return all objects including their respective object id withing the specified one */
+PHP_FUNCTION(snmprealwalk)
+{
+       return _php3_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,3);
+}
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
index 7f6ed0f0b5ca2492c5f8735fd3318be26536ae35..a78a0b99dc068583318d4fe91d213ad326119b1e 100644 (file)
@@ -7,5 +7,7 @@ libphpext_standard_a_SOURCES=\
        html.c image.c info.c link.c mail.c math.c md5.c microtime.c \
        pack.c pageinfo.c rand.c reg.c soundex.c string.c \
        syslog.c type.c uniqid.c url.c iptc.c var.c quot_print.c \
-       cyr_convert.c flock_compat.c crypt.c dl.c head.c
+       cyr_convert.c flock_compat.c crypt.c dl.c head.c mime.c post.c
 
+#number.o: number.c
+#      $(CC) $(CFLAGS) -w@WARNING_LEVEL@ -c $< -o $@
index bf0a5da21ad9b0a1ddbe9fab1916c770791db5c4..e2865ac83f344a1411216e40ef33b928b9735a7c 100644 (file)
 #include <strings.h>
 #endif
 #include "safe_mode.h"
-/*
-#include "functions/basic_functions.h"
-#include "functions/phpmath.h"
-#include "functions/php3_string.h"
-#include "functions/dns.h"
-#include "functions/md5.h"
-#include "functions/html.h"
-#include "functions/post.h"
-#include "functions/exec.h"
-#include "functions/info.h"
-#include "functions/url.h"
-#include "functions/datetime.h"
-#include "functions/fsock.h"
-#include "functions/image.h"
-#include "functions/php3_link.h"
-#include "functions/php3_filestat.h"
-#include "functions/microtime.h"
-#include "functions/pageinfo.h"
-#include "functions/uniqid.h"
-#include "functions/base64.h"
-#include "functions/php3_mail.h"
-#include "functions/php3_var.h"
-#include "functions/php3_iptc.h"
-#include "functions/quot_print.h"
-#include "functions/cyr_convert.h"
-*/
 #if WIN32|WINNT
 #include "win32/unistd.h"
 #endif
index 50703755eb513b7bc8d4f6771c374fa2bfbe581a..69ee82467fa8e8d4177f22941e79e4d4664b3403 100644 (file)
@@ -1,2 +1,14 @@
 /* Define if you have the crypt() function */
 #define HAVE_CRYPT 1
+
+/* Define if you have and want to use libcrypt */
+#define HAVE_LIBCRYPT 0
+
+/* crypt capability checks */
+#undef PHP3_STD_DES_CRYPT
+#undef PHP3_EXT_DES_CRYPT
+#undef PHP3_MD5_CRYPT
+#undef PHP3_BLOWFISH_CRYPT
+
+/* Define if you have libdl (used for dynamic linking) */
+#define HAVE_LIBDL 0
index f44a1df39f67457bfdde0e27073346573a5dfc5d..c20daccc4a2a1a3e3de97e00dec3ebe5ff6935ea 100644 (file)
@@ -1,3 +1,114 @@
 dnl $Id$ -*- sh -*-
 
+divert(1)
+
+dnl
+dnl Check for crypt() capabilities
+dnl
+AC_DEFUN(AC_CRYPT_CAP,[
+
+  AC_MSG_CHECKING([for standard DES crypt])
+  AC_TRY_RUN([
+main() {
+#if HAVE_CRYPT
+    exit (strcmp((char *)crypt("rasmuslerdorf","rl"),"rl.3StKT.4T8M"));
+#else
+       exit(0);
+#endif
+}],[
+    AC_DEFINE(PHP3_STD_DES_CRYPT,1)
+    AC_MSG_RESULT(yes)
+  ],[
+    AC_DEFINE(PHP3_STD_DES_CRYPT,0)
+    AC_MSG_RESULT(no)
+  ],[
+    AC_DEFINE(PHP3_STD_DES_CRYPT,1)
+    AC_MSG_RESULT(cannot check, guessing yes)
+  ])
+
+  AC_MSG_CHECKING([for extended DES crypt])
+  AC_TRY_RUN([
+main() {
+#if HAVE_CRYPT
+    exit (strcmp((char *)crypt("rasmuslerdorf","_J9..rasm"),"_J9..rasmBYk8r9AiWNc"));
+#else
+       exit(0);
+#endif
+}],[
+    AC_DEFINE(PHP3_EXT_DES_CRYPT,1)
+    AC_MSG_RESULT(yes)
+  ],[
+    AC_DEFINE(PHP3_EXT_DES_CRYPT,0)
+    AC_MSG_RESULT(no)
+  ],[
+    AC_DEFINE(PHP3_EXT_DES_CRYPT,0)
+    AC_MSG_RESULT(cannot check, guessing no)
+  ])
+
+  AC_MSG_CHECKING([for MD5 crypt])
+  AC_TRY_RUN([
+main() {
+#if HAVE_CRYPT
+    char salt[15], answer[40];
+
+    salt[0]='$'; salt[1]='1'; salt[2]='$'; 
+    salt[3]='r'; salt[4]='a'; salt[5]='s';
+    salt[6]='m'; salt[7]='u'; salt[8]='s';
+    salt[9]='l'; salt[10]='e'; salt[11]='$';
+    salt[12]='\0';
+    strcpy(answer,salt);
+    strcat(answer,"rISCgZzpwk3UhDidwXvin0");
+    exit (strcmp((char *)crypt("rasmuslerdorf",salt),answer));
+#else
+       exit(0);
+#endif
+}],[
+    AC_DEFINE(PHP3_MD5_CRYPT,1)
+    AC_MSG_RESULT(yes)
+  ],[
+    AC_DEFINE(PHP3_MD5_CRYPT,0)
+    AC_MSG_RESULT(no)
+  ],[
+    AC_DEFINE(PHP3_MD5_CRYPT,0)
+    AC_MSG_RESULT(cannot check, guessing no)
+  ])
+
+  AC_MSG_CHECKING([for Blowfish crypt])
+  AC_TRY_RUN([
+main() {
+#if HAVE_CRYPT
+    char salt[25], answer[70];
+    
+    salt[0]='$'; salt[1]='2'; salt[2]='a'; salt[3]='$'; salt[4]='0'; salt[5]='7'; salt[6]='$'; salt[7]='\0';
+    strcat(salt,"rasmuslerd");
+    strcpy(answer,salt);
+    strcpy(&answer[16],"O............gl95GkTKn53Of.H4YchXl5PwvvW.5ri");
+    exit (strcmp((char *)crypt("rasmuslerdorf",salt),answer));
+#else
+       exit(0);
+#endif
+}],[
+    AC_DEFINE(PHP3_BLOWFISH_CRYPT,1)
+    AC_MSG_RESULT(yes)
+  ],[
+    AC_DEFINE(PHP3_BLOWFISH_CRYPT,0)
+    AC_MSG_RESULT(no)
+  ],[
+    AC_DEFINE(PHP3_BLOWFISH_CRYPT,0)
+    AC_MSG_RESULT(cannot check, guessing no)
+  ])
+])
+
+AC_CHECK_LIB(c, dlopen, [
+ # fake it
+ AC_DEFINE(HAVE_LIBDL) ], [
+ AC_CHECK_LIB(dl, dlopen, [
+  LIBS="-ldl $LIBS"
+  AC_DEFINE(HAVE_LIBDL) ], []) ])
+
+AC_CRYPT_CAP
+
+divert(3)
+
 PHP_EXTENSION(standard)
+
index b664f03afb8f0cfb3c3aa6d7b7bc12b1a2c5d8d0..6e210281cf36a240c7f0fda0caf43d8346113795 100644 (file)
@@ -60,7 +60,7 @@
 
 #include "base64.h"
 #include "file.h"
-#include "functions/post.h"
+#include "post.h"
 #include "url.h"
 #include "fsock.h"
 
diff --git a/ext/standard/mime.c b/ext/standard/mime.c
new file mode 100644 (file)
index 0000000..fdc794a
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include <stdio.h>
+#include "php.h"
+#include "ext/standard/php3_standard.h"
+#include "post.h"
+#include "mime.h"
+#include "zend_globals.h"
+#include "php_globals.h"
+
+#ifndef THREAD_SAFE
+int le_uploads;
+extern HashTable list;
+#endif
+
+#define NEW_BOUNDARY_CHECK 1
+#define SAFE_RETURN { if (namebuf) efree(namebuf); if (filenamebuf) efree(filenamebuf); if (lbuf) efree(lbuf); return; }
+
+/*
+ * Split raw mime stream up into appropriate components
+ */
+void php3_mime_split(char *buf, int cnt, char *boundary, pval *http_post_vars PLS_DC)
+{
+       char *ptr, *loc, *loc2, *s, *name, *filename, *u, *fn;
+       int len, state = 0, Done = 0, rem, urem;
+       long bytes, max_file_size = 0;
+       char *namebuf=NULL, *filenamebuf=NULL, *lbuf=NULL;
+       FILE *fp;
+       int itype;
+       ELS_FETCH();
+
+       ptr = buf;
+       rem = cnt;
+       len = strlen(boundary);
+       while ((ptr - buf < cnt) && !Done) {
+               switch (state) {
+                       case 0:                 /* Looking for mime boundary */
+                               loc = memchr(ptr, *boundary, cnt);
+                               if (loc) {
+                                       if (!strncmp(loc, boundary, len)) {
+
+                                               state = 1;
+                                               rem -= (loc - ptr) + len + 2;
+                                               ptr = loc + len + 2;
+                                       } else {
+                                               rem -= (loc - ptr) + 1;
+                                               ptr = loc + 1;
+                                       }
+                               } else {
+                                       Done = 1;
+                               }
+                               break;
+                       case 1:                 /* Check content-disposition */
+                               if (strncasecmp(ptr, "Content-Disposition: form-data;", 31)) {
+                                       if (rem < 31) {
+                                               SAFE_RETURN;
+                                       }
+                                       php3_error(E_WARNING, "File Upload Mime headers garbled [%c%c%c%c%c]", *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3), *(ptr + 4));
+                                       SAFE_RETURN;
+                               }
+                               loc = memchr(ptr, '\n', rem);
+                               name = strstr(ptr, " name=\"");
+                               if (name && name < loc) {
+                                       name += 7;
+                                       s = memchr(name, '\"', loc - name);
+                                       if (!s) {
+                                               php3_error(E_WARNING, "File Upload Mime headers garbled [%c%c%c%c%c]", *name, *(name + 1), *(name + 2), *(name + 3), *(name + 4));
+                                               SAFE_RETURN;
+                                       }
+                                       if (namebuf) {
+                                               efree(namebuf);
+                                       }
+                                       namebuf = estrndup(name, s-name);
+                                       if (lbuf) {
+                                               efree(lbuf);
+                                       }
+                                       lbuf = emalloc(s-name + MAX(MAX(sizeof("_name"),sizeof("_size")),sizeof("_type")));
+                                       state = 2;
+                                       loc2 = memchr(loc + 1, '\n', rem);
+                                       rem -= (loc2 - ptr) + 1;
+                                       ptr = loc2 + 1;
+                               } else {
+                                       php3_error(E_WARNING, "File upload error - no name component in content disposition");
+                                       SAFE_RETURN;
+                               }
+                               filename = strstr(s, " filename=\"");
+                               if (filename && filename < loc) {
+                                       filename += 11;
+                                       s = memchr(filename, '\"', loc - filename);
+                                       if (!s) {
+                                               php3_error(E_WARNING, "File Upload Mime headers garbled [%c%c%c%c%c]", *filename, *(filename + 1), *(filename + 2), *(filename + 3), *(filename + 4));
+                                               SAFE_RETURN;
+                                       }
+                                       if (filenamebuf) {
+                                               efree(filenamebuf);
+                                       }
+                                       filenamebuf = estrndup(filename, s-filename);
+                                       sprintf(lbuf, "%s_name", namebuf);
+                                       s = strrchr(filenamebuf, '\\');
+                                       if (s && s > filenamebuf) {
+                                               SET_VAR_STRING(lbuf, estrdup(s + 1));
+                                       } else {
+                                               SET_VAR_STRING(lbuf, estrdup(filenamebuf));
+                                       }
+                                       state = 3;
+                                       if ((loc2 - loc) > 2) {
+                                               if (!strncasecmp(loc + 1, "Content-Type:", 13)) {
+                                                       *(loc2 - 1) = '\0';
+                                                       sprintf(lbuf, "%s_type", namebuf);
+                                                       SET_VAR_STRING(lbuf, estrdup(loc + 15));
+                                                       *(loc2 - 1) = '\n';
+                                               }
+                                               rem -= 2;
+                                               ptr += 2;
+                                       }
+                               }
+                               break;
+
+                       case 2:                 /* handle form-data fields */
+                               loc = memchr(ptr, *boundary, rem);
+                               u = ptr;
+                               while (loc) {
+                                       if (!strncmp(loc, boundary, len))
+                                               break;
+                                       u = loc + 1;
+                                       urem = rem - (loc - ptr) - 1;
+                                       loc = memchr(u, *boundary, urem);
+                               }
+                               if (!loc) {
+                                       php3_error(E_WARNING, "File Upload Field Data garbled");
+                                       SAFE_RETURN;
+                               }
+                               *(loc - 4) = '\0';
+
+                               /* Magic function that figures everything out */
+                               _php3_parse_gpc_data(ptr,namebuf,http_post_vars);
+
+                               /* And a little kludge to pick out special MAX_FILE_SIZE */
+                               itype = php3_check_ident_type(namebuf);
+                               if (itype) {
+                                       u = strchr(namebuf, '[');
+                                       if (u)
+                                               *u = '\0';
+                               }
+                               if (!strcmp(namebuf, "MAX_FILE_SIZE")) {
+                                       max_file_size = atol(ptr);
+                               }
+                               if (itype) {
+                                       if (u)
+                                               *u = '[';
+                               }
+                               rem     -= (loc - ptr);
+                               ptr = loc;
+                               state = 0;
+                               break;
+
+                       case 3:                 /* Handle file */
+                               loc = memchr(ptr, *boundary, rem);
+                               u = ptr;
+                               while (loc) {
+                                       if (!strncmp(loc, boundary, len)
+#if NEW_BOUNDARY_CHECK
+                                               && (loc-2>buf && *(loc-2)=='-' && *(loc-1)=='-') /* ensure boundary is prefixed with -- */
+                                               && (loc-2==buf || *(loc-3)=='\n') /* ensure beginning of line */
+#endif
+                                               ) {
+                                               break;
+                                       }
+                                       u = loc + 1;
+                                       urem = rem - (loc - ptr) - 1;
+                                       loc = memchr(u, *boundary, urem);
+                               }
+                               if (!loc) {
+                                       php3_error(E_WARNING, "File Upload Error - No Mime boundary found after start of file header");
+                                       SAFE_RETURN;
+                               }
+                               fn = tempnam(PG(upload_tmp_dir), "php");
+                               if ((loc - ptr - 4) > PG(upload_max_filesize)) {
+                                       php3_error(E_WARNING, "Max file size of %ld bytes exceeded - file [%s] not saved", PG(upload_max_filesize),namebuf);
+                                       bytes=0;        
+                                       SET_VAR_STRING(namebuf, estrdup("none"));
+                               } else if (max_file_size && ((loc - ptr - 4) > max_file_size)) {
+                                       php3_error(E_WARNING, "Max file size exceeded - file [%s] not saved", namebuf);
+                                       bytes = 0;
+                                       SET_VAR_STRING(namebuf, estrdup("none"));
+                               } else if ((loc - ptr - 4) <= 0) {
+                                       bytes = 0;
+                                       SET_VAR_STRING(namebuf, estrdup("none"));
+                               } else {
+                                       fp = fopen(fn, "w");
+                                       if (!fp) {
+                                               php3_error(E_WARNING, "File Upload Error - Unable to open temporary file [%s]", fn);
+                                               SAFE_RETURN;
+                                       }
+                                       bytes = fwrite(ptr, 1, loc - ptr - 4, fp);
+                                       fclose(fp);
+                                       php3_list_insert(fn,GLOBAL(le_uploads));  /* Tell PHP about the file so the destructor can unlink it later */
+                                       if (bytes < (loc - ptr - 4)) {
+                                               php3_error(E_WARNING, "Only %d bytes were written, expected to write %ld", bytes, loc - ptr - 4);
+                                       }
+                                       SET_VAR_STRING(namebuf, estrdup(fn));
+                               }
+                               sprintf(lbuf, "%s_size", namebuf);
+                               SET_VAR_LONG(lbuf, bytes);
+                               state = 0;
+                               rem -= (loc - ptr);
+                               ptr = loc;
+                               break;
+               }
+       }
+       SAFE_RETURN;
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/standard/mime.h b/ext/standard/mime.h
new file mode 100644 (file)
index 0000000..df5d787
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _MIME_H
+#define _MIME_H
+
+#include "php_globals.h"
+
+extern void php3_mime_split(char *buf, int cnt, char *boundary, pval *http_post_vars PLS_DC);
+
+#endif
index 77ccafb40fd755f6d15f7ff5db8b2610ae8fd589..a3920e30e705971c8d7c49429ffa038617f5d7ef 100644 (file)
@@ -62,6 +62,9 @@
 #include "type.h"
 #include "dl.h"
 #include "php3_crypt.h"
+#include "head.h"
+#include "post.h"
+#include "mime.h"
 
 #define standard_module_ptr basic_functions_module_ptr
 
diff --git a/ext/standard/post.c b/ext/standard/post.c
new file mode 100644 (file)
index 0000000..2244509
--- /dev/null
@@ -0,0 +1,498 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
+   +----------------------------------------------------------------------+
+ */
+/* $Id: */
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include <stdio.h>
+#include "php.h"
+#include "php3_standard.h"
+#include "php_globals.h"
+
+#include "zend_globals.h"
+
+/*
+ * php3_getpost()
+ *
+ * This reads the post form data into a string.
+ * Remember to free this pointer when done with it.
+ */
+static char *php3_getpost(pval *http_post_vars PLS_DC)
+{
+       char *buf = NULL;
+       const char *ctype;
+#if MODULE_MAGIC_NUMBER > 19961007
+       char argsbuffer[HUGE_STRING_LEN];
+#else
+       int bytes;
+#endif
+       int length, cnt;
+       int file_upload = 0;
+       char *mb;
+       char boundary[100];
+       TLS_VARS;
+       
+       ctype = GLOBAL(request_info).content_type;
+       if (!ctype) {
+               php3_error(E_WARNING, "POST Error: content-type missing");
+               return NULL;
+       }
+       if (strncasecmp(ctype, "application/x-www-form-urlencoded", 33) && strncasecmp(ctype, "multipart/form-data", 19)
+#if HAVE_FDFLIB
+ && strncasecmp(ctype, "application/vnd.fdf", 19)
+#endif
+      ) {
+               php3_error(E_WARNING, "Unsupported content-type: %s", ctype);
+               return NULL;
+       }
+       if (!strncasecmp(ctype, "multipart/form-data", 19)) {
+               file_upload = 1;
+               mb = strchr(ctype, '=');
+               if (mb) {
+                       strncpy(boundary, mb + 1, sizeof(boundary));
+               } else {
+                       php3_error(E_WARNING, "File Upload Error: No MIME boundary found");
+                       php3_error(E_WARNING, "There should have been a \"boundary=something\" in the Content-Type string");
+                       php3_error(E_WARNING, "The Content-Type string was: \"%s\"", ctype);
+                       return NULL;
+               }
+       }
+       length = GLOBAL(request_info).content_length;
+       cnt = length;
+       buf = (char *) emalloc((length + 1) * sizeof(char));
+       if (!buf) {
+               php3_error(E_WARNING, "Unable to allocate memory in php3_getpost()");
+               return NULL;
+       }
+#if FHTTPD
+    memcpy(buf,req->databuffer,length);
+    buf[length]=0;
+#else
+#if MODULE_MAGIC_NUMBER > 19961007
+       if (should_client_block(GLOBAL(php3_rqst))) {
+               void (*handler) (int);
+               int dbsize, len_read, dbpos = 0;
+
+               hard_timeout("copy script args", GLOBAL(php3_rqst));    /* start timeout timer */
+               handler = signal(SIGPIPE, SIG_IGN);             /* Ignore sigpipes for now */
+               while ((len_read = get_client_block(GLOBAL(php3_rqst), argsbuffer, HUGE_STRING_LEN)) > 0) {
+                       if ((dbpos + len_read) > length)
+                               dbsize = length - dbpos;
+                       else
+                               dbsize = len_read;
+                       reset_timeout(GLOBAL(php3_rqst));       /* Make sure we don't timeout */
+                       memcpy(buf + dbpos, argsbuffer, dbsize);
+                       dbpos += dbsize;
+               }
+               signal(SIGPIPE, handler);       /* restore normal sigpipe handling */
+               kill_timeout(GLOBAL(php3_rqst));        /* stop timeout timer */
+       }
+#else
+       cnt = 0;
+       do {
+#if APACHE
+               bytes = read_client_block(php3_rqst, buf + cnt, length - cnt);
+#endif
+#if CGI_BINARY
+               bytes = fread(buf + cnt, 1, length - cnt, stdin);
+#endif
+#if USE_SAPI
+               bytes = GLOBAL(sapi_rqst)->readclient(GLOBAL(sapi_rqst)->scid,buf + cnt, 1, length - cnt);
+#endif
+               cnt += bytes;
+       } while (bytes && cnt < length);
+#endif
+#endif
+       if (file_upload) {
+               php3_mime_split(buf, cnt, boundary, http_post_vars PLS_CC);
+               efree(buf);
+               return NULL;
+       }
+       buf[cnt] = '\0';
+
+#if HAVE_FDFLIB
+       if (!strncasecmp(ctype, "application/vnd.fdf", 19)) {
+               pval *postdata_ptr = (pval *) emalloc(sizeof(pval));
+               
+               postdata_ptr->type = IS_STRING;
+               postdata_ptr->value.str.val = (char *) estrdup(buf);
+               postdata_ptr->value.str.len = cnt;
+               postdata_ptr->refcount=1;
+               postdata_ptr->is_ref=0;
+               _php3_hash_add(&GLOBAL(symbol_table), "HTTP_FDF_DATA", sizeof("HTTP_FDF_DATA"), postdata_ptr, sizeof(pval *),NULL);
+       }
+#endif
+       return (buf);
+}
+
+
+/*
+ * parse Get/Post/Cookie string and create appropriate variable
+ *
+ * This is a tad ugly because it was yanked out of the middle of
+ * the old TreatData function.  This is a temporary measure filling 
+ * the gap until a more flexible parser can be built to do this.
+ */
+void _php3_parse_gpc_data(char *val, char *var, pval *track_vars_array)
+{
+       int var_type;
+       char *ind, *tmp = NULL, *ret = NULL;
+       int var_len;
+       pval *entry;
+       ELS_FETCH();
+       PLS_FETCH();
+       
+       var_type = php3_check_ident_type(var);
+       if (var_type == GPC_INDEXED_ARRAY) {
+               ind = php3_get_ident_index(var);
+               if (PG(magic_quotes_gpc)) {
+                       ret = _php3_addslashes(ind, 0, NULL, 1);
+               } else {
+                       ret = ind;
+               }
+       }
+       if (var_type & GPC_ARRAY) {             /* array (indexed or not */
+               tmp = strchr(var, '[');
+               if (tmp) {
+                       *tmp = '\0';
+               }
+       }
+       /* ignore leading spaces in the variable name */
+       while (*var && *var==' ') {
+               var++;
+       }
+       var_len = strlen(var);
+       if (var_len==0) { /* empty variable name, or variable name with a space in it */
+               return;
+       }
+
+       /* ensure that we don't have spaces or dots in the variable name (not binary safe) */
+       for (tmp=var; *tmp; tmp++) {
+               switch(*tmp) {
+                       case ' ':
+                       case '.':
+                               *tmp='_';
+                               break;
+               }
+       }
+
+       tmp = estrdup(val);
+       if (var_type & GPC_ARRAY) {
+               pval *arr1, *arr2;
+               pval **arr_ptr;
+
+               /* If the array doesn't exist, create it */
+               if (_php3_hash_find(EG(active_symbol_table), var, var_len+1, (void **) &arr_ptr) == FAILURE) {
+                       arr1 = (pval *) emalloc(sizeof(pval));
+                       arr1->refcount=1;
+                       arr1->is_ref=0;
+                       if (array_init(arr1)==FAILURE) {
+                               return;
+                       }
+                       _php3_hash_update(EG(active_symbol_table), var, var_len+1, &arr1, sizeof(pval *), NULL);
+                       if (track_vars_array) {
+                               arr2 = (pval *) emalloc(sizeof(pval));
+                               arr2->refcount=1;
+                               arr2->is_ref=0;
+                               if (array_init(arr2)==FAILURE) {
+                                       return;
+                               }
+                               _php3_hash_update(track_vars_array->value.ht, var, var_len+1, (void *) &arr2, sizeof(pval *),NULL);
+                       }
+               } else {
+                       if ((*arr_ptr)->type!=IS_ARRAY) {
+                               if (--(*arr_ptr) > 0) {
+                                       *arr_ptr = (pval *) emalloc(sizeof(pval));
+                                       (*arr_ptr)->refcount=1;
+                                       (*arr_ptr)->is_ref=0;
+                               } else {
+                                       pval_destructor(*arr_ptr);
+                               }
+                               if (array_init(*arr_ptr)==FAILURE) {
+                                       return;
+                               }
+                               if (track_vars_array) {
+                                       arr2 = (pval *) emalloc(sizeof(pval));
+                                       arr2->refcount=1;
+                                       arr2->is_ref=0;
+                                       if (array_init(arr2)==FAILURE) {
+                                               return;
+                                       }
+                                       _php3_hash_update(track_vars_array->value.ht, var, var_len+1, (void *) &arr2, sizeof(pval *),NULL);
+                               }
+                       }
+                       arr1 = *arr_ptr;
+                       if (track_vars_array && _php3_hash_find(track_vars_array->value.ht, var, var_len+1, (void **) &arr_ptr) == FAILURE) {
+                               return;
+                       }
+                       arr2 = *arr_ptr;
+               }
+               /* Now create the element */
+               entry = (pval *) emalloc(sizeof(pval));
+               entry->refcount=1;
+               entry->is_ref=0;
+               if (PG(magic_quotes_gpc)) {
+                       entry->value.str.val = _php3_addslashes(tmp, 0, &entry->value.str.len, 0);
+               } else {
+                       entry->value.str.len = strlen(tmp);
+                       entry->value.str.val = estrndup(tmp,entry->value.str.len);
+               }
+               entry->type = IS_STRING;
+
+               /* And then insert it */
+               if (ret) {              /* indexed array */
+                       if (php3_check_type(ret) == IS_LONG) {
+                               _php3_hash_index_update(arr1->value.ht, atol(ret), &entry, sizeof(pval *),NULL);        /* s[ret]=tmp */
+                               if (track_vars_array) {
+                                       _php3_hash_index_update(arr2->value.ht, atol(ret), &entry, sizeof(pval *),NULL);
+                                       entry->refcount++;
+                               }
+                       } else {
+                               _php3_hash_update(arr1->value.ht, ret, strlen(ret)+1, &entry, sizeof(pval *),NULL);     /* s["ret"]=tmp */
+                               if (track_vars_array) {
+                                       _php3_hash_update(arr2->value.ht, ret, strlen(ret)+1, &entry, sizeof(pval *),NULL);
+                                       entry->refcount++;
+                               }
+                       }
+                       efree(ret);
+                       ret = NULL;
+               } else {                /* non-indexed array */
+                       _php3_hash_next_index_insert(arr1->value.ht, &entry, sizeof(pval *),NULL);
+                       if (track_vars_array) {
+                               _php3_hash_next_index_insert(arr2->value.ht, &entry, sizeof(pval *),NULL);
+                               entry->refcount++;
+                       }
+               }
+       } else {                        /* we have a normal variable */
+               pval *entry = (pval *) emalloc(sizeof(pval));
+               
+               if (PG(magic_quotes_gpc)) {
+                       entry->value.str.val = _php3_addslashes(tmp, 0, &entry->value.str.len, 0);
+               } else {
+                       entry->value.str.len = strlen(tmp);
+                       entry->value.str.val = estrndup(tmp,entry->value.str.len);
+               }
+               entry->type = IS_STRING;
+               entry->refcount=1;
+               entry->is_ref=0;
+               _php3_hash_update(EG(active_symbol_table), var, var_len+1, (void *) &entry, sizeof(pval *),NULL);
+               if (track_vars_array) {
+                       pval_copy_constructor(entry);
+                       _php3_hash_update(track_vars_array->value.ht, var, var_len+1, (void *) &entry, sizeof(pval *),NULL);
+               }
+       }
+
+       if (tmp) efree(tmp);
+}
+
+
+void php3_treat_data(int arg, char *str)
+{
+       char *res = NULL, *var, *val;
+       pval *array_ptr;
+       ELS_FETCH();
+       PLS_FETCH();
+       
+       switch (arg) {
+               case PARSE_POST:
+               case PARSE_GET:
+               case PARSE_COOKIE:
+                       if (PG(track_vars)) {
+                               array_ptr = (pval *) emalloc(sizeof(pval));
+                               array_init(array_ptr);
+                               array_ptr->refcount=1;
+                               array_ptr->is_ref=0;
+                               switch (arg) {
+                                       case PARSE_POST:
+                                               _php3_hash_add(&EG(symbol_table), "HTTP_POST_VARS", sizeof("HTTP_POST_VARS"), &array_ptr, sizeof(pval *),NULL);
+                                               break;
+                                       case PARSE_GET:
+                                               _php3_hash_add(&EG(symbol_table), "HTTP_GET_VARS", sizeof("HTTP_GET_VARS"), &array_ptr, sizeof(pval *),NULL);
+                                               break;
+                                       case PARSE_COOKIE:
+                                               _php3_hash_add(&EG(symbol_table), "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS"), &array_ptr, sizeof(pval *),NULL);
+                                               break;
+                               }
+                       } else {
+                               array_ptr=NULL;
+                       }
+                       break;
+               default:
+                       array_ptr=NULL;
+                       break;
+       }
+
+       if (arg == PARSE_POST) {
+               res = php3_getpost(array_ptr PLS_CC);
+       } else if (arg == PARSE_GET) {          /* Get data */
+               var = GLOBAL(request_info).query_string;
+               if (var && *var) {
+                       res = (char *) estrdup(var);
+               }
+       } else if (arg == PARSE_COOKIE) {               /* Cookie data */
+               var = (char *)GLOBAL(request_info).cookies;
+               if (var && *var) {
+                       res = (char *) estrdup(var);
+               }
+       } else if (arg == PARSE_STRING) {               /* String data */
+               res = str;
+       }
+       if (!res) {
+               return;
+       }
+       
+       if (arg == PARSE_COOKIE) {
+               var = strtok(res, ";");
+       } else if (arg == PARSE_POST) {
+               var = strtok(res, "&");
+       } else {
+               var = strtok(res, PG(arg_separator));
+       }
+
+       while (var) {
+               val = strchr(var, '=');
+               if (val) { /* have a value */
+                       *val++ = '\0';
+                       /* FIXME: XXX: not binary safe, discards returned length */
+                       _php3_urldecode(var, strlen(var));
+                       _php3_urldecode(val, strlen(val));
+                       _php3_parse_gpc_data(val,var,array_ptr);
+               }
+               if (arg == PARSE_COOKIE) {
+                       var = strtok(NULL, ";");
+               } else if (arg == PARSE_POST) {
+                       var = strtok(NULL, "&");
+               } else {
+                       var = strtok(NULL, PG(arg_separator));
+               }
+       }
+       efree(res);
+}
+
+
+void php3_TreatHeaders(void)
+{
+#if APACHE
+#if MODULE_MAGIC_NUMBER > 19961007
+       const char *s = NULL;
+#else
+       char *s = NULL;
+#endif
+       char *t;
+       char *user, *type;
+       int len;
+       char *escaped_str;
+       PLS_FETCH();
+
+       if (GLOBAL(php3_rqst)->headers_in)
+               s = table_get(GLOBAL(php3_rqst)->headers_in, "Authorization");
+       if (!s)
+               return;
+
+       /* Check to make sure that this URL isn't authenticated
+          using a traditional auth module mechanism */
+       if (auth_type(GLOBAL(php3_rqst))) {
+               /*php3_error(E_WARNING, "Authentication done by server module\n");*/
+               return;
+       }
+       if (strcmp(t=getword(GLOBAL(php3_rqst)->pool, &s, ' '), "Basic")) {
+               /* Client tried to authenticate using wrong auth scheme */
+               php3_error(E_WARNING, "client used wrong authentication scheme (%s)", t);
+               return;
+       }
+       t = uudecode(GLOBAL(php3_rqst)->pool, s);
+#if MODULE_MAGIC_NUMBER > 19961007
+       user = getword_nulls_nc(GLOBAL(php3_rqst)->pool, &t, ':');
+#else
+       user = getword(GLOBAL(php3_rqst)->pool, &t, ':');
+#endif
+       type = "Basic";
+
+       if (user) {
+               if (PG(magic_quotes_gpc)) {
+                       escaped_str = _php3_addslashes(user, 0, &len, 0);
+                       SET_VAR_STRINGL("PHP_AUTH_USER", escaped_str, len);
+               } else {
+                       SET_VAR_STRING("PHP_AUTH_USER", estrdup(user));
+               }
+       }
+       if (t) {
+               if (PG(magic_quotes_gpc)) {
+                       escaped_str = _php3_addslashes(t, 0, &len, 0);
+                       SET_VAR_STRINGL("PHP_AUTH_PW", escaped_str, len);
+               } else {
+                       SET_VAR_STRING("PHP_AUTH_PW", estrdup(t));
+               }
+       }
+       if (type) {
+               if (PG(magic_quotes_gpc)) {
+                       escaped_str = _php3_addslashes(type, 0, &len, 0);
+                       SET_VAR_STRINGL("PHP_AUTH_TYPE", escaped_str, len);
+               } else {
+                       SET_VAR_STRING("PHP_AUTH_TYPE", estrdup(type));
+               }
+       }
+#endif
+#if FHTTPD
+       int i,len;
+       struct rline *l;
+       char *type;
+       char *escaped_str;
+
+       if(req && req->remote_user){
+               for(i=0; i < req->nlines; i++){
+                       l=req->lines+i;
+                       if((l->paramc > 1)&&!strcasecmp(l->params[0], "REMOTE_PW")){
+                               type = "Basic";
+                               if (PG(magic_quotes_gpc)) {
+                                       escaped_str = _php3_addslashes(type, 0, &len, 0);
+                                       SET_VAR_STRINGL("PHP_AUTH_TYPE", escaped_str, len);
+                                       escaped_str = _php3_addslashes(l->params[1], 0, &len, 0);
+                                       SET_VAR_STRINGL("PHP_AUTH_PW", escaped_str, len);
+                                       escaped_str = _php3_addslashes(req->remote_user, 0, &len, 0);
+                                       SET_VAR_STRINGL("PHP_AUTH_USER", escaped_str, len);
+
+                               } else {
+                                       SET_VAR_STRING("PHP_AUTH_TYPE", estrdup(type));
+                                       SET_VAR_STRING("PHP_AUTH_PW", estrdup(l->params[1]));
+                                       SET_VAR_STRING("PHP_AUTH_USER", estrdup(req->remote_user));
+                               }
+                               i=req->nlines;
+                       }
+               }
+       }
+#endif
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/standard/post.h b/ext/standard/post.h
new file mode 100644 (file)
index 0000000..37920a8
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+#ifndef _POST_H
+#define _POST_H
+
+#define PARSE_POST 0
+#define PARSE_GET 1
+#define PARSE_COOKIE 2
+#define PARSE_STRING 3
+
+extern void php3_treat_data(int arg, char *str);
+extern void php3_TreatHeaders(void);
+extern void _php3_parse_gpc_data(char *, char *, pval *track_vars_array);
+
+#endif
index 43457ba44a8882d6c13b1589ec53060369d2008f..b05605275c6e9ac6764ec3a0d7a92e546cc8f5d7 100644 (file)
@@ -37,7 +37,7 @@
 #include <stdio.h>
 #include "php.h"
 #include "reg.h"
-#include "functions/post.h"
+#include "post.h"
 #include "php3_string.h"
 #if HAVE_SETLOCALE
 #include <locale.h>
index a602ee0eb7fa37cabefa57c4e1f1bc44b6572fc8..feb277c4c304466882878127a2c15861cab0008d 100644 (file)
@@ -36,7 +36,7 @@
 #include "php.h"
 #include "fopen-wrappers.h"
 #include "reg.h"
-#include "functions/post.h"
+#include "post.h"
 #include "php3_string.h"
 #if HAVE_SETLOCALE
 #include <locale.h>
diff --git a/ext/sybase/Makefile.am b/ext/sybase/Makefile.am
new file mode 100644 (file)
index 0000000..97c3e06
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_sybase.a
+libphpext_sybase_a_SOURCES=sybase.c sybase-ct.c
+
diff --git a/ext/sybase/Makefile.in b/ext/sybase/Makefile.in
new file mode 100644 (file)
index 0000000..224e6b5
--- /dev/null
@@ -0,0 +1,270 @@
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id$
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DISTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+APACHE_INCLUDE = @APACHE_INCLUDE@
+APACHE_TARGET = @APACHE_TARGET@
+APXS = @APXS@
+APXS_LDFLAGS = @APXS_LDFLAGS@
+BINNAME = @BINNAME@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CFLAGS_SHLIB = @CFLAGS_SHLIB@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+EXTINFO_DEPS = @EXTINFO_DEPS@
+EXTRA_LIBS = @EXTRA_LIBS@
+EXT_LIBS = @EXT_LIBS@
+EXT_SUBDIRS = @EXT_SUBDIRS@
+FHTTPD_LIB = @FHTTPD_LIB@
+FHTTPD_TARGET = @FHTTPD_TARGET@
+HSREGEX = @HSREGEX@
+INSTALL_IT = @INSTALL_IT@
+LDFLAGS_SHLIB = @LDFLAGS_SHLIB@
+LDFLAGS_SHLIB_EXPORT = @LDFLAGS_SHLIB_EXPORT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+PERL_PATH = @PERL_PATH@
+PHP_BUILD_DATE = @PHP_BUILD_DATE@
+PHP_DEBUG = @PHP_DEBUG@
+PHP_LIBS = @PHP_LIBS@
+PHP_VERSION = @PHP_VERSION@
+PROG_SENDMAIL = @PROG_SENDMAIL@
+RANLIB = @RANLIB@
+RDYNAMIC_LFLAGS = @RDYNAMIC_LFLAGS@
+REGEX_LIB = @REGEX_LIB@
+STRONGHOLD = @STRONGHOLD@
+VERSION = @VERSION@
+WARNING_LEVEL = @WARNING_LEVEL@
+YACC = @YACC@
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_sybase.a
+libphpext_sybase_a_SOURCES=sybase.c sybase-ct.c
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libphpext_sybase_a_LIBADD = 
+libphpext_sybase_a_OBJECTS =  sybase.o sybase-ct.o
+AR = ar
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(libphpext_sybase_a_SOURCES)
+OBJECTS = $(libphpext_sybase_a_OBJECTS)
+
+all: Makefile $(LIBRARIES)
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: @MAINT@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps ext/sybase/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+       $(COMPILE) -c $<
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libphpext_sybase.a: $(libphpext_sybase_a_OBJECTS) $(libphpext_sybase_a_DEPENDENCIES)
+       -rm -f libphpext_sybase.a
+       $(AR) cru libphpext_sybase.a $(libphpext_sybase_a_OBJECTS) $(libphpext_sybase_a_LIBADD)
+       $(RANLIB) libphpext_sybase.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = ext/sybase
+
+distdir: $(DISTFILES)
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
+       done
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
+install-strip:
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f Makefile $(DISTCLEANFILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-generic
+
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
+               mostlyclean
+
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-generic clean
+       -rm -f config.status
+
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-generic distclean
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-exec install-data install uninstall all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ext/sybase/config.h.stub b/ext/sybase/config.h.stub
new file mode 100644 (file)
index 0000000..15ce449
--- /dev/null
@@ -0,0 +1,6 @@
+/* Define if you have libdnet_stub (used for Sybase support) */
+#define HAVE_LIBDNET_STUB 0
+
+#define HAVE_SYBASE 0
+
+#define HAVE_SYBASE_CT 0
diff --git a/ext/sybase/config.m4 b/ext/sybase/config.m4
new file mode 100644 (file)
index 0000000..34de483
--- /dev/null
@@ -0,0 +1,73 @@
+dnl $Id$
+
+AC_MSG_CHECKING(for Sybase support)
+AC_ARG_WITH(sybase,
+[  --with-sybase[=DIR]     Include Sybase-DB support.  DIR is the Sybase home
+                          directory, defaults to /home/sybase.],
+[
+  if test "$withval" != "no"; then
+    if test "$withval" = "yes"; then
+      SYBASE_INCDIR=/home/sybase/include
+      SYBASE_LIBDIR=/home/sybase/lib
+    else
+      SYBASE_INCDIR=$withval/include
+      SYBASE_LIBDIR=$withval/lib
+    fi
+    SYBASE_INCLUDE=-I$SYBASE_INCDIR
+    SYBASE_LFLAGS="-L$SYBASE_LIBDIR -L$SYBASE_LIBDIR"
+    SYBASE_LIBS=-lsybdb
+    AC_MSG_RESULT(yes)
+    PHP_EXTENSION(sybase)
+    AC_CHECK_LIB(dnet_stub, dnet_addr,
+     [ SYBASE_LIBS="$SYBASE_LIBS -ldnet_stub"
+        AC_DEFINE(HAVE_LIBDNET_STUB)
+     ])
+    AC_DEFINE(HAVE_SYBASE)
+    EXTRA_LIBS="$EXTRA_LIBS $SYBASE_LFLAGS $SYBASE_LIBS"
+    INCLUDES="$INCLUDES $SYBASE_INCLUDE"
+  else
+    AC_MSG_RESULT(no)
+  fi
+],[
+  AC_MSG_RESULT(no)
+])
+
+
+AC_MSG_CHECKING(for Sybase-CT support)
+AC_ARG_WITH(sybase-ct,
+[  --with-sybase-ct[=DIR]  Include Sybase-CT support.  DIR is the Sybase home
+                          directory, defaults to /home/sybase.],
+[
+  if test "$withval" != "no"; then
+    AC_MSG_RESULT(yes)
+    if test -z "$SYBASE_LIBS"; then
+      PHP_EXTENSION(sybase)
+    fi
+    AC_DEFINE(HAVE_SYBASE_CT)
+    if test "$withval" = "yes"; then
+      SYBASE_CT_INCDIR=/home/sybase/include
+      SYBASE_CT_LIBDIR=/home/sybase/lib
+    else
+      SYBASE_CT_INCDIR=$withval/include
+      SYBASE_CT_LIBDIR=$withval/lib
+    fi
+    SYBASE_CT_INCLUDE=-I$SYBASE_CT_INCDIR
+    SYBASE_CT_LFLAGS="-L$SYBASE_CT_LIBDIR"
+    SYBASE_CT_LIBS="-lcs -lct -lcomn -lintl"
+    old_LDFLAGS=$LDFLAGS
+    LDFLAGS="$LDFLAGS -L$SYBASE_CT_LIBDIR"
+    AC_CHECK_LIB(tcl, netg_errstr,
+              [ SYBASE_CT_LIBS="$SYBASE_CT_LIBS -ltcl" ],
+              [ SYBASE_CT_LIBS="$SYBASE_CT_LIBS -lsybtcl" ],
+              [ $SYBASE_CT_LIBS ])
+    AC_CHECK_LIB(insck, insck__getVdate,
+              [ SYBASE_CT_LIBS="$SYBASE_CT_LIBS -linsck" ])
+      LDFLAGS=$old_LDFLAGS
+    EXTRA_LIBS="$EXTRA_LIBS $SYBASE_CT_LFLAGS $SYBASE_CT_LIBS"
+    INCLUDES="$INCLUDES $SYBASE_CT_INCLUDE"
+  else
+    AC_MSG_RESULT(no)
+  fi
+],[
+  AC_MSG_RESULT(no)
+])
diff --git a/ext/sybase/php3_sybase-ct.h b/ext/sybase/php3_sybase-ct.h
new file mode 100644 (file)
index 0000000..1ce0a30
--- /dev/null
@@ -0,0 +1,123 @@
+/* 
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Zeev Suraski <zeev@zend.com>                                |
+   +----------------------------------------------------------------------+
+ */
+
+
+/* $Id$ */
+
+#ifndef _PHP3_SYBASE_CT_H
+#define _PHP3_SYBASE_CT_H
+
+#if COMPILE_DL
+#undef HAVE_SYBASE_CT
+#define HAVE_SYBASE_CT 1
+#endif
+
+#if HAVE_SYBASE_CT
+
+#define CTLIB_VERSION CS_VERSION_100
+
+extern php3_module_entry sybct_module_entry;
+#define sybct_module_ptr &sybct_module_entry
+
+extern int php3_minit_sybct(INIT_FUNC_ARGS);
+extern int php3_rinit_sybct(INIT_FUNC_ARGS);
+extern int php3_mshutdown_sybct(SHUTDOWN_FUNC_ARGS);
+extern int php3_rshutdown_sybct(SHUTDOWN_FUNC_ARGS);
+extern void php3_info_sybct(void);
+extern void php3_sybct_connect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_pconnect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_close(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_select_db(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_query(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_free_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_get_last_message(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_num_rows(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_num_fields(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_fetch_row(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_fetch_array(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_fetch_object(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_data_seek(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_affected_rows(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_field_seek(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_min_client_severity(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_min_server_severity(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybct_fetch_field(INTERNAL_FUNCTION_PARAMETERS);
+
+
+#include <ctpublic.h>
+
+typedef struct {
+       long default_link;
+       long num_links,num_persistent;
+       long max_links,max_persistent;
+       long allow_persistent;
+       char *appname;
+       char *hostname;
+       char *server_message;
+       int le_link,le_plink,le_result;
+       long min_server_severity, min_client_severity;
+       long cfg_min_server_severity, cfg_min_client_severity;
+} sybct_module;
+
+typedef struct {
+       CS_CONNECTION *connection;
+       CS_COMMAND *cmd;
+       int valid;
+       int deadlock;
+       int dead;
+       long affected_rows;
+} sybct_link;
+
+#define SYBASE_ROWS_BLOCK 128
+
+typedef struct {
+       char *name,*column_source;
+       int max_length, numeric;
+       CS_INT type;
+} sybct_field;
+
+typedef struct {
+       pval **data;
+       sybct_field *fields;
+       sybct_link *sybct_ptr;
+       int cur_row,cur_field;
+       int num_rows,num_fields;
+} sybct_result;
+
+
+extern sybct_module php3_sybct_module;
+
+#else
+
+#define sybct_module_ptr NULL
+
+#endif
+
+#endif /* _PHP3_SYBASE_CT_H */
diff --git a/ext/sybase/php3_sybase.h b/ext/sybase/php3_sybase.h
new file mode 100644 (file)
index 0000000..dbfcdd7
--- /dev/null
@@ -0,0 +1,141 @@
+/* 
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Zeev Suraski <zeev@zend.com>                                |
+   +----------------------------------------------------------------------+
+ */
+
+
+/* $Id$ */
+
+#ifndef _PHP3_SYBASE_H
+#define _PHP3_SYBASE_H
+
+#if COMPILE_DL
+#undef HAVE_SYBASE
+#define HAVE_SYBASE 1
+#endif
+
+#if HAVE_SYBASE
+
+extern php3_module_entry sybase_module_entry;
+#define sybase_module_ptr &sybase_module_entry
+
+extern int php3_minit_sybase(INIT_FUNC_ARGS);
+extern int php3_rinit_sybase(INIT_FUNC_ARGS);
+extern int php3_mshutdown_sybase(SHUTDOWN_FUNC_ARGS);
+extern int php3_rshutdown_sybase(SHUTDOWN_FUNC_ARGS);
+extern void php3_info_sybase(void);
+extern void php3_sybase_connect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_pconnect(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_close(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_select_db(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_query(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_free_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_get_last_message(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_num_rows(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_num_fields(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_fetch_row(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_fetch_array(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_fetch_object(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_data_seek(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_field_seek(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_min_error_severity(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_min_message_severity(INTERNAL_FUNCTION_PARAMETERS);
+
+extern void php3_sybase_db_query(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_list_fields(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_fetch_lengths(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_fetch_field(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_field_seek(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_free_result(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_field_name(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_field_table(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_field_len(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_field_type(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sybase_field_flags(INTERNAL_FUNCTION_PARAMETERS);
+
+
+
+#include <sybfront.h>
+#include <sybdb.h>
+#include <syberror.h>
+
+#define coltype(j) dbcoltype(sybase_ptr->link,j)
+#define intcol(i) ((int) *(DBINT *) dbdata(sybase_ptr->link,i))
+#define smallintcol(i) ((int) *(DBSMALLINT *) dbdata(sybase_ptr->link,i))
+#define tinyintcol(i) ((int) *(DBTINYINT *) dbdata(sybase_ptr->link,i))
+#define anyintcol(j) (coltype(j)==SYBINT4?intcol(j):(coltype(j)==SYBINT2?smallintcol(j):tinyintcol(j)))
+#define charcol(i) ((DBCHAR *) dbdata(sybase_ptr->link,i))
+#define floatcol(i) ((float) *(DBFLT8 *) dbdata(sybase_ptr->link,i))
+
+typedef struct sybase_link_struct sybase_link;
+
+typedef struct {
+       long default_link;
+       long num_links,num_persistent;
+       long max_links,max_persistent;
+       long allow_persistent;
+       char *appname;
+       char *server_message;
+       int le_link,le_plink,le_result;
+       long min_error_severity,min_message_severity;
+       long cfg_min_error_severity,cfg_min_message_severity;
+       long compatability_mode;
+} sybase_module;
+
+struct sybase_link_struct {
+       LOGINREC *login;
+       DBPROCESS *link;
+       int valid;
+};
+
+#define SYBASE_ROWS_BLOCK 128
+
+typedef struct {
+       char *name,*column_source;
+       int max_length, numeric;
+       int type;
+} sybase_field;
+
+typedef struct {
+       pval **data;
+       sybase_field *fields;
+       sybase_link *sybase_ptr;
+       int cur_row,cur_field;
+       int num_rows,num_fields;
+} sybase_result;
+
+
+extern sybase_module php3_sybase_module;
+
+#else
+
+#define sybase_module_ptr NULL
+
+#endif
+
+#endif /* _PHP3_SYBASE_H */
diff --git a/ext/sybase/setup.stub b/ext/sybase/setup.stub
new file mode 100644 (file)
index 0000000..58e0b78
--- /dev/null
@@ -0,0 +1,11 @@
+# $Source$
+# $Id$
+
+define_option with-sybase 'Sybase support?' yesnodir \
+    'no /home/sybase Sybase install' \
+'     Whether to build PHP with Sybase support (DBLib only).\n
+     More info about Sybase can be found at http://www.sybase.com/.'
+
+define_option with-sybase-ct 'Sybase-CT support?' yesnodir \
+    'no /home/sybase Sybase-CT install' \
+'     Whether to build PHP with Sybase-CT support.'
diff --git a/ext/sybase/sybase-ct.c b/ext/sybase/sybase-ct.c
new file mode 100644 (file)
index 0000000..7f45658
--- /dev/null
@@ -0,0 +1,1652 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Zeev Suraski <zeev@zend.com>                                |
+   |          Tom May <tom@go2net.com>                                    |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+
+#ifndef MSVC5
+#include "config.h"
+#endif
+#include "php.h"
+#include "php3_sybase-ct.h"
+#include "ext/standard/php3_standard.h"
+#include "php_globals.h"
+
+#if HAVE_SYBASE_CT
+
+
+
+function_entry sybct_functions[] = {
+       {"sybase_connect",              php3_sybct_connect,                     NULL},
+       {"sybase_pconnect",             php3_sybct_pconnect,            NULL},
+       {"sybase_close",                php3_sybct_close,                       NULL},
+       {"sybase_select_db",    php3_sybct_select_db,           NULL},
+       {"sybase_query",                php3_sybct_query,                       NULL},
+       {"sybase_free_result",  php3_sybct_free_result,         NULL},
+       {"sybase_num_rows",             php3_sybct_num_rows,            NULL},
+       {"sybase_num_fields",   php3_sybct_num_fields,          NULL},
+       {"sybase_fetch_row",    php3_sybct_fetch_row,           NULL},
+       {"sybase_fetch_array",  php3_sybct_fetch_array,         NULL},
+       {"sybase_fetch_object", php3_sybct_fetch_object,        NULL},
+       {"sybase_data_seek",    php3_sybct_data_seek,           NULL},
+       {"sybase_fetch_field",  php3_sybct_fetch_field,         NULL},
+       {"sybase_field_seek",   php3_sybct_field_seek,          NULL},
+       {"sybase_result",               php3_sybct_result,                      NULL},
+       {"sybase_affected_rows",php3_sybct_affected_rows,       NULL},
+       {"sybase_min_client_severity",  php3_sybct_min_client_severity,         NULL},
+       {"sybase_min_server_severity",  php3_sybct_min_server_severity,         NULL},
+       {"mssql_connect",               php3_sybct_connect,                     NULL},
+       {"mssql_pconnect",              php3_sybct_pconnect,            NULL},
+       {"mssql_close",                 php3_sybct_close,                       NULL},
+       {"mssql_select_db",             php3_sybct_select_db,           NULL},
+       {"mssql_query",                 php3_sybct_query,                       NULL},
+       {"mssql_free_result",   php3_sybct_free_result,         NULL},
+       {"mssql_num_rows",              php3_sybct_num_rows,            NULL},
+       {"mssql_num_fields",    php3_sybct_num_fields,          NULL},
+       {"mssql_fetch_row",             php3_sybct_fetch_row,           NULL},
+       {"mssql_fetch_array",   php3_sybct_fetch_array,         NULL},
+       {"mssql_fetch_object",  php3_sybct_fetch_object,        NULL},
+       {"mssql_data_seek",             php3_sybct_data_seek,           NULL},
+       {"mssql_fetch_field",   php3_sybct_fetch_field,         NULL},
+       {"mssql_field_seek",    php3_sybct_field_seek,          NULL},
+       {"mssql_result",                php3_sybct_result,                      NULL},
+       {"mssql_affected_rows", php3_sybct_affected_rows,       NULL},
+       {"mssql_min_client_severity",   php3_sybct_min_client_severity,         NULL},
+       {"mssql_min_server_severity",   php3_sybct_min_server_severity,         NULL},
+       {NULL, NULL, NULL}
+};
+
+php3_module_entry sybct_module_entry = {
+       "Sybase SQL - CT", sybct_functions, php3_minit_sybct, php3_mshutdown_sybct, php3_rinit_sybct, php3_rshutdown_sybct, php3_info_sybct, STANDARD_MODULE_PROPERTIES
+};
+
+#if COMPILE_DL
+php3_module_entry *get_module() { return &sybct_module_entry; }
+#endif
+
+THREAD_LS sybct_module php3_sybct_module;
+THREAD_LS static CS_CONTEXT *context;
+THREAD_LS static HashTable *resource_list,*resource_plist;
+
+#define CHECK_LINK(link) { if (link==-1) { php3_error(E_WARNING,"Sybase:  A link to the server could not be established"); RETURN_FALSE; } }
+
+
+static int _clean_invalid_results(list_entry *le)
+{
+       if (le->type == php3_sybct_module.le_result) {
+               sybct_link *sybct_ptr = ((sybct_result *) le->ptr)->sybct_ptr;
+               
+               if (!sybct_ptr->valid) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+
+static void _free_sybct_result(sybct_result *result)
+{
+       int i,j;
+
+       if (result->data) {
+               for (i=0; i<result->num_rows; i++) {
+                       for (j=0; j<result->num_fields; j++) {
+                               pval_destructor(&result->data[i][j]);
+                       }
+                       efree(result->data[i]);
+               }
+               efree(result->data);
+       }
+       
+       if (result->fields) {
+               for (i=0; i<result->num_fields; i++) {
+                       STR_FREE(result->fields[i].name);
+                       STR_FREE(result->fields[i].column_source);
+               }
+               efree(result->fields);
+       }
+
+       efree(result);
+}
+
+
+static void _close_sybct_link(sybct_link *sybct_ptr)
+{
+       CS_INT con_status;
+
+       sybct_ptr->valid = 0;
+       _php3_hash_apply(resource_list,(int (*)(void *))_clean_invalid_results);
+
+       /* Non-persistent connections will always be connected or we wouldn't
+        * get here, but since we want to check the death status anyway
+        * we might as well double-check the connect status.
+        */
+       if (ct_con_props(sybct_ptr->connection, CS_GET, CS_CON_STATUS,
+                                        &con_status, CS_UNUSED, NULL)!=CS_SUCCEED) {
+               php3_error(E_WARNING,"Sybase:  Unable to get connection status on close");
+               /* Assume the worst. */
+               con_status = CS_CONSTAT_CONNECTED | CS_CONSTAT_DEAD;
+       }
+       if (con_status & CS_CONSTAT_CONNECTED) {
+               if ((con_status & CS_CONSTAT_DEAD) || ct_close(sybct_ptr->connection, CS_UNUSED)!=CS_SUCCEED) {
+                       ct_close(sybct_ptr->connection, CS_FORCE_CLOSE);
+               }
+       }
+
+       ct_con_drop(sybct_ptr->connection);
+       efree(sybct_ptr);
+       php3_sybct_module.num_links--;
+}
+
+
+static void _close_sybct_plink(sybct_link *sybct_ptr)
+{
+       CS_INT con_status;
+
+       /* Persistent connections may have been closed before a failed
+        * reopen attempt.
+        */
+       if (ct_con_props(sybct_ptr->connection, CS_GET, CS_CON_STATUS,
+                                        &con_status, CS_UNUSED, NULL)!=CS_SUCCEED) {
+               php3_error(E_WARNING,"Sybase:  Unable to get connection status on close");
+               /* Assume the worst. */
+               con_status = CS_CONSTAT_CONNECTED | CS_CONSTAT_DEAD;
+       }
+       if (con_status & CS_CONSTAT_CONNECTED) {
+               if ((con_status & CS_CONSTAT_DEAD) || ct_close(sybct_ptr->connection, CS_UNUSED)!=CS_SUCCEED) {
+                       ct_close(sybct_ptr->connection, CS_FORCE_CLOSE);
+               }
+       }
+
+       ct_con_drop(sybct_ptr->connection);
+       free(sybct_ptr);
+       php3_sybct_module.num_persistent--;
+       php3_sybct_module.num_links--;
+}
+
+
+static CS_RETCODE _client_message_handler(CS_CONTEXT *context, CS_CONNECTION *connection, CS_CLIENTMSG *errmsg)
+{
+       if (CS_SEVERITY(errmsg->msgnumber) >= php3_sybct_module.min_client_severity) {
+               php3_error(E_WARNING,"Sybase:  Client message:  %s (severity %d)",errmsg->msgstring, CS_SEVERITY(errmsg->msgnumber));
+       }
+
+       /* If this is a timeout message, return CS_FAIL to cancel the
+        * operation and mark the connection as dead.
+        */
+       if (CS_SEVERITY(errmsg->msgnumber) == CS_SV_RETRY_FAIL &&
+               CS_NUMBER(errmsg->msgnumber) == 63 &&
+               CS_ORIGIN(errmsg->msgnumber) == 2 &&
+               CS_LAYER(errmsg->msgnumber) == 1)
+       {
+               return CS_FAIL;
+       }
+
+    return CS_SUCCEED;
+}
+
+
+static CS_RETCODE _server_message_handler(CS_CONTEXT *context, CS_CONNECTION *connection, CS_SERVERMSG *srvmsg)
+{
+       if (srvmsg->severity >= php3_sybct_module.min_server_severity) {
+               php3_error(E_WARNING,"Sybase:  Server message:  %s (severity %d, procedure %s)",
+                                       srvmsg->text, srvmsg->severity, ((srvmsg->proclen>0) ? srvmsg->proc : "N/A"));
+       }
+
+       /* If this is a deadlock message, set the connection's deadlock flag
+        * so we will retry the request.  Sorry about the bare constant here,
+        * but it's not defined anywhere and it's a "well-known" number.
+        */
+       if (srvmsg->msgnumber == 1205) {
+               sybct_link *sybct;
+
+               if (ct_con_props(connection, CS_GET, CS_USERDATA, &sybct, CS_SIZEOF(sybct), NULL)==CS_SUCCEED) {
+                   sybct->deadlock = 1;
+               }
+               else {
+                       /* oh well */
+               }
+       }
+
+    return CS_SUCCEED;
+}
+
+
+int php3_minit_sybct(INIT_FUNC_ARGS)
+{
+       long timeout;
+
+       if (cs_ctx_alloc(CTLIB_VERSION, &context)!=CS_SUCCEED || ct_init(context,CTLIB_VERSION)!=CS_SUCCEED) {
+               return FAILURE;
+       }
+       /* Initialize message handlers */
+       
+       if (ct_callback(context, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID *)_server_message_handler)!=CS_SUCCEED) {
+               php3_error(E_WARNING,"Sybase:  Unable to set server message handler");
+       }
+       if (ct_callback(context, NULL, CS_SET, CS_CLIENTMSG_CB, (CS_VOID *)_client_message_handler)!=CS_SUCCEED) {
+               php3_error(E_WARNING,"Sybase:  Unable to set client message handler");
+       }
+       
+       /* Set datetime conversion format to "Nov  3 1998  8:06PM".
+        * This is the default format for the ct-lib that comes with
+        * Sybase ASE 11.5.1 for Solaris, but the Linux libraries that
+        * come with 11.0.3.3 default to "03/11/98" which is singularly
+        * useless.  This levels the playing field for all platforms.
+        */
+       {
+               CS_INT dt_convfmt = CS_DATES_SHORT;
+               if (cs_dt_info(context, CS_SET, NULL, CS_DT_CONVFMT, CS_UNUSED, &dt_convfmt, sizeof(dt_convfmt), NULL)!=CS_SUCCEED) {
+                       php3_error(E_WARNING,"Sybase:  Unable to set datetime conversion format");
+               }
+       }
+
+       /* Set the login and command timeouts.  These are per-context and
+        * can't be set with ct_con_props(), so set them globally from
+        * their config values if requested.  The defaults are 1 minute
+        * for CS_LOGIN_TIMEOUT and CS_NO_LIMIT for CS_TIMEOUT.  The latter
+        * especially is fairly useless for web applications.
+        * Note that depite some noise in the documentation about using
+        * signals to implement timeouts, they are actually implemented
+        * by using poll() or select() on Solaris and Linux.
+        */
+       if (cfg_get_long("sybct.login_timeout",&timeout)==SUCCESS) {
+               CS_INT cs_login_timeout = timeout;
+               if (ct_config(context, CS_SET, CS_LOGIN_TIMEOUT, &cs_login_timeout, CS_UNUSED, NULL)!=CS_SUCCEED) {
+                       php3_error(E_WARNING,"Sybase:  Unable to set login timeoutt");
+               }
+       }
+       if (cfg_get_long("sybct.timeout",&timeout)==SUCCESS) {
+               CS_INT cs_timeout = timeout;
+               if (ct_config(context, CS_SET, CS_TIMEOUT, &cs_timeout, CS_UNUSED, NULL)!=CS_SUCCEED) {
+                       php3_error(E_WARNING,"Sybase:  Unable to set timeout");
+               }
+       }
+
+       if (cfg_get_long("sybct.allow_persistent",&php3_sybct_module.allow_persistent)==FAILURE) {
+               php3_sybct_module.allow_persistent=1;
+       }
+       if (cfg_get_long("sybct.max_persistent",&php3_sybct_module.max_persistent)==FAILURE) {
+               php3_sybct_module.max_persistent=-1;
+       }
+       if (cfg_get_long("sybct.max_links",&php3_sybct_module.max_links)==FAILURE) {
+               php3_sybct_module.max_links=-1;
+       }
+       if (cfg_get_long("sybct.min_server_severity",&php3_sybct_module.cfg_min_server_severity)==FAILURE) {
+               php3_sybct_module.cfg_min_server_severity=10;
+       }
+       if (cfg_get_long("sybct.min_client_severity",&php3_sybct_module.cfg_min_client_severity)==FAILURE) {
+               php3_sybct_module.cfg_min_client_severity=10;
+       }
+       
+       if (cfg_get_string("sybct.hostname",&php3_sybct_module.hostname)==FAILURE
+               || php3_sybct_module.hostname[0]==0) {
+               php3_sybct_module.hostname=NULL;
+       }
+
+       php3_sybct_module.num_persistent=0;
+       php3_sybct_module.le_link = register_list_destructors(_close_sybct_link,NULL);
+       php3_sybct_module.le_plink = register_list_destructors(NULL,_close_sybct_plink);
+       php3_sybct_module.le_result = register_list_destructors(_free_sybct_result,NULL);
+
+       return SUCCESS;
+}
+
+
+int php3_rinit_sybct(INIT_FUNC_ARGS)
+{
+       php3_sybct_module.default_link=-1;
+       php3_sybct_module.num_links = php3_sybct_module.num_persistent;
+       php3_sybct_module.appname = estrndup("PHP 3.0",7);
+       php3_sybct_module.server_message = NULL;
+       php3_sybct_module.min_server_severity = php3_sybct_module.cfg_min_server_severity;
+       php3_sybct_module.min_client_severity = php3_sybct_module.cfg_min_client_severity;
+       return SUCCESS;
+}
+
+int php3_mshutdown_sybct(SHUTDOWN_FUNC_ARGS)
+{
+/*     ct_exit(context,CS_UNUSED);
+       cs_ctx_drop(context); */
+       return SUCCESS;
+}
+
+int php3_rshutdown_sybct(SHUTDOWN_FUNC_ARGS)
+{
+       efree(php3_sybct_module.appname);
+       if (php3_sybct_module.server_message) {
+               efree(php3_sybct_module.server_message);
+       }
+       return SUCCESS;
+}
+
+
+static int _php3_sybct_really_connect(sybct_link *sybct, char *host, char *user, char *passwd)
+{
+       /* set a CS_CONNECTION record */
+       if (ct_con_alloc(context, &sybct->connection)!=CS_SUCCEED) {
+               php3_error(E_WARNING,"Sybase:  Unable to allocate connection record");
+               return 0;
+       }
+       
+       /* Note - this saves a copy of sybct, not a pointer to it. */
+       if (ct_con_props(sybct->connection, CS_SET, CS_USERDATA, &sybct, CS_SIZEOF(sybct), NULL)!=CS_SUCCEED) {
+               php3_error(E_WARNING,"Sybase:  Unable to set userdata");
+               ct_con_drop(sybct->connection);
+               return 0;
+       }
+
+       if (user) {
+               ct_con_props(sybct->connection, CS_SET, CS_USERNAME, user, CS_NULLTERM, NULL);
+       }
+       if (passwd) {
+               ct_con_props(sybct->connection, CS_SET, CS_PASSWORD, passwd, CS_NULLTERM, NULL);
+       }
+       ct_con_props(sybct->connection, CS_SET, CS_APPNAME, php3_sybct_module.appname, CS_NULLTERM, NULL);
+
+       if (php3_sybct_module.hostname) {
+               ct_con_props(sybct->connection, CS_SET, CS_HOSTNAME, php3_sybct_module.hostname, CS_NULLTERM, NULL);
+       }
+
+       sybct->valid = 1;
+       sybct->dead = 0;
+
+       /* create the link */
+       if (ct_connect(sybct->connection, host, CS_NULLTERM)!=CS_SUCCEED) {
+               php3_error(E_WARNING,"Sybase:  Unable to connect");
+               ct_con_drop(sybct->connection);
+               return 0;
+       }
+
+       if (ct_cmd_alloc(sybct->connection,&sybct->cmd)!=CS_SUCCEED) {
+               php3_error(E_WARNING,"Sybase:  Unable to allocate command record");
+               ct_close(sybct->connection,CS_UNUSED);
+               ct_con_drop(sybct->connection);
+               return 0;
+       }
+
+       return 1;
+}
+
+
+static void php3_sybct_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent)
+{
+       char *user,*passwd,*host;
+       char *hashed_details;
+       int hashed_details_length;
+       sybct_link *sybct_ptr;
+
+       resource_list = list;
+       resource_plist = plist;
+               
+       switch(ARG_COUNT(ht)) {
+               case 0: /* defaults */
+                       host=user=passwd=NULL;
+                       hashed_details_length=5+3;
+                       hashed_details = (char *) emalloc(hashed_details_length+1);
+                       strcpy(hashed_details,"sybct___");
+                       break;
+               case 1: {
+                               pval *yyhost;
+                               
+                               if (getParameters(ht, 1, &yyhost)==FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               host = yyhost->value.str.val;
+                               user=passwd=NULL;
+                               hashed_details_length = yyhost->value.str.len+5+3;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"sybct_%s__",yyhost->value.str.val);
+                       }
+                       break;
+               case 2: {
+                               pval *yyhost,*yyuser;
+                               
+                               if (getParameters(ht, 2, &yyhost, &yyuser)==FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               convert_to_string(yyuser);
+                               host = yyhost->value.str.val;
+                               user = yyuser->value.str.val;
+                               passwd=NULL;
+                               hashed_details_length = yyhost->value.str.len+yyuser->value.str.len+5+3;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"sybct_%s_%s_",yyhost->value.str.val,yyuser->value.str.val);
+                       }
+                       break;
+               case 3: {
+                               pval *yyhost,*yyuser,*yypasswd;
+                       
+                               if (getParameters(ht, 3, &yyhost, &yyuser, &yypasswd) == FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               convert_to_string(yyuser);
+                               convert_to_string(yypasswd);
+                               host = yyhost->value.str.val;
+                               user = yyuser->value.str.val;
+                               passwd = yypasswd->value.str.val;
+                               hashed_details_length = yyhost->value.str.len+yyuser->value.str.len+yypasswd->value.str.len+5+3;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"sybct_%s_%s_%s",yyhost->value.str.val,yyuser->value.str.val,yypasswd->value.str.val); /* SAFE */
+                       }
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+
+       if (!php3_sybct_module.allow_persistent) {
+               persistent=0;
+       }
+       if (persistent) {
+               list_entry *le;
+
+               /* try to find if we already have this link in our persistent list */
+               if (_php3_hash_find(plist, hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {  /* we don't */
+                       list_entry new_le;
+
+                       if (php3_sybct_module.max_links!=-1 && php3_sybct_module.num_links>=php3_sybct_module.max_links) {
+                               php3_error(E_WARNING,"Sybase:  Too many open links (%d)",php3_sybct_module.num_links);
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       if (php3_sybct_module.max_persistent!=-1 && php3_sybct_module.num_persistent>=php3_sybct_module.max_persistent) {
+                               php3_error(E_WARNING,"Sybase:  Too many open persistent links (%d)",php3_sybct_module.num_persistent);
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+
+                       sybct_ptr = (sybct_link *) malloc(sizeof(sybct_link));
+                       if (!_php3_sybct_really_connect(sybct_ptr, host, user, passwd)) {
+                               free(sybct_ptr);
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+
+                       /* hash it up */
+                       new_le.type = php3_sybct_module.le_plink;
+                       new_le.ptr = sybct_ptr;
+                       if (_php3_hash_update(plist, hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry),NULL)==FAILURE) {
+                               ct_close(sybct_ptr->connection, CS_UNUSED);
+                               ct_con_drop(sybct_ptr->connection);
+                               free(sybct_ptr);
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       php3_sybct_module.num_persistent++;
+                       php3_sybct_module.num_links++;
+               } else {  /* we do */
+                       CS_INT con_status;
+
+                       if (le->type != php3_sybct_module.le_plink) {
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       
+                       sybct_ptr = (sybct_link *) le->ptr;
+
+                       /* If the link has died, close it and overwrite it with a new one. */
+
+                       if (ct_con_props(sybct_ptr->connection, CS_GET, CS_CON_STATUS,
+                                                        &con_status, CS_UNUSED, NULL)!=CS_SUCCEED) {
+                               php3_error(E_WARNING,"Sybase:  Unable to get connection status");
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       if (!(con_status & CS_CONSTAT_CONNECTED) || (con_status & CS_CONSTAT_DEAD) || sybct_ptr->dead) {
+                               sybct_link sybct;
+
+                               if (con_status & CS_CONSTAT_CONNECTED) {
+                                       ct_close(sybct_ptr->connection, CS_FORCE_CLOSE);
+                               }
+                               /* Create a new connection, then replace the old
+                                * connection.  If we fail to create a new connection,
+                                * put the old one back so there will be a connection,
+                                * even if it is a non-functional one.  This is because
+                                * code may still be holding an id for this connection
+                                * so we can't free the CS_CONNECTION.
+                                * (This is actually totally hokey, it would be better
+                                * to just ct_con_drop() the connection and set
+                                * sybct_ptr->connection to NULL, then test it for
+                                * NULL before trying to use it elsewhere . . .)
+                                */
+                               memcpy(&sybct,sybct_ptr,sizeof(sybct_link));
+                               if (!_php3_sybct_really_connect(sybct_ptr, host, user, passwd)) {
+                                       memcpy(sybct_ptr,&sybct,sizeof(sybct_link));
+                                       efree(hashed_details);
+                                       RETURN_FALSE;
+                               }
+                               ct_con_drop(sybct.connection); /* drop old connection */
+                       }
+               }
+               return_value->value.lval = php3_list_insert(sybct_ptr,php3_sybct_module.le_plink);
+               return_value->type = IS_LONG;
+       } else { /* non persistent */
+               list_entry *index_ptr,new_index_ptr;
+               
+               /* first we check the hash for the hashed_details key.  if it exists,
+                * it should point us to the right offset where the actual sybct link sits.
+                * if it doesn't, open a new sybct link, add it to the resource list,
+                * and add a pointer to it with hashed_details as the key.
+                */
+               if (_php3_hash_find(list,hashed_details,hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
+                       int type,link;
+                       void *ptr;
+
+                       if (index_ptr->type != le_index_ptr) {
+                               efree(hashed_details);
+                               RETURN_FALSE;
+                       }
+                       link = (int) index_ptr->ptr;
+                       ptr = php3_list_find(link,&type);   /* check if the link is still there */
+                       if (ptr && (type==php3_sybct_module.le_link || type==php3_sybct_module.le_plink)) {
+                               return_value->value.lval = php3_sybct_module.default_link = link;
+                               return_value->type = IS_LONG;
+                               efree(hashed_details);
+                               return;
+                       } else {
+                               _php3_hash_del(list,hashed_details,hashed_details_length+1);
+                       }
+               }
+               if (php3_sybct_module.max_links!=-1 && php3_sybct_module.num_links>=php3_sybct_module.max_links) {
+                       php3_error(E_WARNING,"Sybase:  Too many open links (%d)",php3_sybct_module.num_links);
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+
+               sybct_ptr = (sybct_link *) emalloc(sizeof(sybct_link));
+               if (!_php3_sybct_really_connect(sybct_ptr, host, user, passwd)) {
+                       efree(sybct_ptr);
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+
+               /* add it to the list */
+               return_value->value.lval = php3_list_insert(sybct_ptr,php3_sybct_module.le_link);
+               return_value->type = IS_LONG;
+               
+               /* add it to the hash */
+               new_index_ptr.ptr = (void *) return_value->value.lval;
+               new_index_ptr.type = le_index_ptr;
+               if (_php3_hash_update(list,hashed_details,hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry),NULL)==FAILURE) {
+                       ct_close(sybct_ptr->connection, CS_UNUSED);
+                       ct_con_drop(sybct_ptr->connection);
+                       efree(sybct_ptr);
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+               php3_sybct_module.num_links++;
+       }
+       efree(hashed_details);
+       php3_sybct_module.default_link=return_value->value.lval;
+}
+
+
+static int php3_sybct_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
+{
+       if (php3_sybct_module.default_link==-1) { /* no link opened yet, implicitly open one */
+               HashTable dummy;
+
+               _php3_hash_init(&dummy,0,NULL,NULL,0);
+               php3_sybct_do_connect(&dummy,return_value,list,plist,0);
+               _php3_hash_destroy(&dummy);
+       }
+       return php3_sybct_module.default_link;
+}
+
+
+void php3_sybct_connect(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_sybct_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
+}
+
+void php3_sybct_pconnect(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_sybct_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
+
+
+void php3_sybct_close(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybct_link_index;
+       int id,type;
+       
+       switch (ARG_COUNT(ht)) {
+               case 0:
+                       id = php3_sybct_module.default_link;
+                       break;
+               case 1:
+                       if (getParameters(ht, 1, &sybct_link_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(sybct_link_index);
+                       id = sybct_link_index->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_link && type!=php3_sybct_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a Sybase link index",id);
+               RETURN_FALSE;
+       }
+       
+       php3_list_delete(id);
+       RETURN_TRUE;
+}
+       
+
+static int exec_cmd(sybct_link *sybct_ptr,char *cmdbuf)
+{
+       CS_RETCODE retcode;
+       CS_INT restype;
+       int failure=0;
+
+       /* Fail if we already marked this connection dead. */
+
+       if (sybct_ptr->dead) {
+               return FAILURE;
+       }
+
+       /*
+        ** Get a command handle, store the command string in it, and
+        ** send it to the server.
+        */
+       
+       if (ct_command(sybct_ptr->cmd, CS_LANG_CMD, cmdbuf, CS_NULLTERM, CS_UNUSED)!=CS_SUCCEED) {
+               sybct_ptr->dead = 1;
+               return FAILURE;
+       }
+       if (ct_send(sybct_ptr->cmd)!=CS_SUCCEED) {
+               sybct_ptr->dead = 1;
+               return FAILURE;
+       }
+       
+       while ((retcode = ct_results(sybct_ptr->cmd, &restype))==CS_SUCCEED) {
+               switch ((int) restype) {
+                       case CS_CMD_SUCCEED:
+                       case CS_CMD_DONE:
+                               break;
+               
+                       case CS_CMD_FAIL:
+                               failure=1;
+                               break;
+                       
+                       case CS_STATUS_RESULT:
+                               ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_CURRENT);
+                               break;
+                       
+                       default:
+                               failure=1;
+                               break;
+               }
+               if (failure) {
+                       ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL);
+                       return FAILURE;
+               }
+       }
+
+       switch (retcode) {
+               case CS_END_RESULTS:
+                       return SUCCESS;
+                       break;
+
+               case CS_FAIL:
+                       /* Hopefully this either cleans up the connection, or the
+                        * connection ends up marked dead so it will be reopened
+                        * if it is persistent.  We may want to do
+                        * ct_close(CS_FORCE_CLOSE) if ct_cancel() fails; see the
+                        * doc for ct_results()==CS_FAIL.
+                        */
+                       ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL);
+                       /* Don't take chances with the vagaries of ct-lib.  Mark it
+                        * dead ourselves.
+                        */
+                       sybct_ptr->dead = 1;
+                       return FAILURE;
+
+               default:
+                       return FAILURE;
+       }
+}
+
+
+void php3_sybct_select_db(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *db,*sybct_link_index;
+       int id,type;
+       char *cmdbuf;
+       sybct_link  *sybct_ptr;
+       
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &db)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       id = php3_sybct_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &db, &sybct_link_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(sybct_link_index);
+                       id = sybct_link_index->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       CHECK_LINK(id);
+       
+       sybct_ptr = (sybct_link *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_link && type!=php3_sybct_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a Sybase link index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_string(db);
+       cmdbuf = (char *) emalloc(sizeof("use ")+db->value.str.len+1);
+       sprintf(cmdbuf,"use %s",db->value.str.val); /* SAFE */
+
+       if (exec_cmd(sybct_ptr,cmdbuf)==FAILURE) {
+               efree(cmdbuf);
+               RETURN_FALSE;
+       } else {
+               efree(cmdbuf);
+               RETURN_TRUE;
+       }
+}
+
+
+static sybct_result * _php3_sybct_fetch_result_set (sybct_link *sybct_ptr)
+{
+       int num_fields;
+       sybct_result *result;
+       char **tmp_buffer;
+       CS_INT *lengths;
+       CS_SMALLINT *indicators;
+       unsigned char *numerics;
+       CS_INT *types;
+       CS_DATAFMT *datafmt;
+       int i,j,retcode;
+       int blocks_initialized=1;
+
+       /* The following is more or less the equivalent of mysql_store_result().
+        * fetch all rows from the server into the row buffer, thus:
+        * 1)  Being able to fire up another query without explicitly reading all rows
+        * 2)  Having numrows accessible
+        */
+
+       if (ct_res_info(sybct_ptr->cmd, CS_NUMDATA, &num_fields, CS_UNUSED, NULL)!=CS_SUCCEED) {
+               return NULL;
+       }
+       
+       result = (sybct_result *) emalloc(sizeof(sybct_result));
+       result->data = (pval **) emalloc(sizeof(pval *)*SYBASE_ROWS_BLOCK);
+       result->fields = NULL;
+       result->sybct_ptr = sybct_ptr;
+       result->cur_field=result->cur_row=result->num_rows=0;
+       result->num_fields = num_fields;
+
+       tmp_buffer = (char **) emalloc(sizeof(char *)*num_fields);
+       lengths = (CS_INT *) emalloc(sizeof(CS_INT)*num_fields);
+       indicators = (CS_SMALLINT *) emalloc(sizeof(CS_INT)*num_fields);
+       datafmt = (CS_DATAFMT *) emalloc(sizeof(CS_DATAFMT)*num_fields);
+       numerics = (unsigned char *) emalloc(sizeof(unsigned char)*num_fields);
+       types = (CS_INT *) emalloc(sizeof(CS_INT)*num_fields);
+       
+
+       for (i=0; i<num_fields; i++) {
+               ct_describe(sybct_ptr->cmd,i+1,&datafmt[i]);
+               types[i] = datafmt[i].datatype;
+               switch (datafmt[i].datatype) {
+                       case CS_CHAR_TYPE:
+                       case CS_VARCHAR_TYPE:
+                       case CS_TEXT_TYPE:
+                       case CS_IMAGE_TYPE:
+                               datafmt[i].maxlength++;
+                               numerics[i] = 0;
+                               break;
+                       case CS_BINARY_TYPE:
+                       case CS_VARBINARY_TYPE:
+                               datafmt[i].maxlength *= 2;
+                               datafmt[i].maxlength++;
+                               numerics[i] = 0;
+                               break;
+                       case CS_BIT_TYPE:
+                       case CS_TINYINT_TYPE:
+                               datafmt[i].maxlength = 4;
+                               numerics[i] = 1;
+                               break;
+                       case CS_SMALLINT_TYPE:
+                               datafmt[i].maxlength = 7;
+                               numerics[i] = 1;
+                               break;
+                       case CS_INT_TYPE:
+                               datafmt[i].maxlength = 12;
+                               numerics[i] = 1;
+                               break;
+                       case CS_REAL_TYPE:
+                       case CS_FLOAT_TYPE:
+                               datafmt[i].maxlength = 24;
+                               numerics[i] = 1;
+                               break;
+                       case CS_MONEY_TYPE:
+                       case CS_MONEY4_TYPE:
+                               datafmt[i].maxlength = 24;
+                               numerics[i] = 0;
+                               break;
+                       case CS_DATETIME_TYPE:
+                       case CS_DATETIME4_TYPE:
+                               datafmt[i].maxlength = 30;
+                               numerics[i] = 0;
+                               break;
+                       case CS_NUMERIC_TYPE:
+                       case CS_DECIMAL_TYPE:
+                               datafmt[i].maxlength = datafmt[i].precision + 3;
+                               numerics[i] = 1;
+                               break;
+                       default:
+                               datafmt[i].maxlength++;
+                               numerics[i] = 0;
+                               break;
+               }
+               tmp_buffer[i] = (char *)emalloc(datafmt[i].maxlength);
+               datafmt[i].datatype = CS_CHAR_TYPE;
+               datafmt[i].format = CS_FMT_NULLTERM;
+               ct_bind(sybct_ptr->cmd,i+1,&datafmt[i],tmp_buffer[i],&lengths[i],&indicators[i]);
+       }
+       
+       while ((retcode=ct_fetch(sybct_ptr->cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED,NULL))==CS_SUCCEED
+                       || retcode==CS_ROW_FAIL) {
+               /*
+               if (retcode==CS_ROW_FAIL) {
+                       php3_error(E_WARNING,"Sybase:  Error reading row %d",result->num_rows);
+               }
+               */
+               i = result->num_rows++;
+               if (result->num_rows > blocks_initialized*SYBASE_ROWS_BLOCK) {
+                       result->data = (pval **) erealloc(result->data,sizeof(pval *)*SYBASE_ROWS_BLOCK*(++blocks_initialized));
+               }
+               result->data[i] = (pval *) emalloc(sizeof(pval)*num_fields);
+               for (j=0; j<num_fields; j++) {
+                       if (indicators[j] == -1) { /* null value */
+                               var_reset(&result->data[i][j]);
+                       } else {
+                               result->data[i][j].value.str.len = lengths[j]-1;  /* we don't need the NULL in the length */
+                               result->data[i][j].value.str.val = estrndup(tmp_buffer[j],lengths[j]);
+                               result->data[i][j].type = IS_STRING;
+                       }
+               }
+       }
+
+       if (retcode != CS_END_DATA) {
+               _free_sybct_result(result);
+               result = NULL;
+       } else {
+               result->fields = (sybct_field *) emalloc(sizeof(sybct_field)*num_fields);
+               j=0;
+               for (i=0; i<num_fields; i++) {
+                       char computed_buf[16];
+               
+                       if (datafmt[i].namelen>0) {
+                               result->fields[i].name = estrndup(datafmt[i].name,datafmt[i].namelen);
+                       } else {
+                               if (j>0) {
+                                       snprintf(computed_buf,16,"computed%d",j);
+                               } else {
+                                       strcpy(computed_buf,"computed");
+                               }
+                               result->fields[i].name = estrdup(computed_buf);
+                               j++;
+                       }
+                       result->fields[i].column_source = empty_string;
+                       result->fields[i].max_length = datafmt[i].maxlength-1;
+                       result->fields[i].numeric = numerics[i];
+                       result->fields[i].type = types[i];
+               }
+       }
+
+       efree(datafmt);
+       efree(lengths);
+       efree(indicators);
+       efree(numerics);
+       efree(types);
+       for (i=0; i<num_fields; i++) {
+               efree(tmp_buffer[i]);
+       }
+       efree(tmp_buffer);
+
+       return result;
+}
+
+
+void php3_sybct_query(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *query,*sybct_link_index;
+       int id,type;
+       sybct_link *sybct_ptr;
+       sybct_result *result;
+       CS_INT restype;
+       CS_RETCODE retcode;
+       enum {
+               Q_RESULT,                               /* Success with results. */
+               Q_SUCCESS,                              /* Success but no results. */
+               Q_FAILURE,                              /* Failure, no results. */
+       } status;
+       
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &query)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       id = php3_sybct_module.default_link;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &query, &sybct_link_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(sybct_link_index);
+                       id = sybct_link_index->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       sybct_ptr = (sybct_link *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_link && type!=php3_sybct_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a Sybase link index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_string(query);
+       
+       /* Fail if we already marked this connection dead. */
+
+       if (sybct_ptr->dead) {
+               RETURN_FALSE;
+       }
+
+       /* Repeat until we don't deadlock. */
+
+       for (;;) {
+               result = NULL;
+               sybct_ptr->deadlock = 0;
+               sybct_ptr->affected_rows = 0;
+
+               /* On Solaris 11.5, ct_command() can be moved outside the
+                * loop, but not on Linux 11.0.
+                */
+               if (ct_command(sybct_ptr->cmd, CS_LANG_CMD, query->value.str.val, CS_NULLTERM, CS_UNUSED)!=CS_SUCCEED) {
+                       /* If this didn't work, the connection is screwed but
+                        * ct-lib might not set CS_CONSTAT_DEAD.  So set our own
+                        * flag.  This happens sometimes when the database is restarted
+                        * and/or its machine is rebooted, and ct_command() returns
+                        * CS_BUSY for some reason.
+                        */
+                       sybct_ptr->dead = 1;
+                   RETURN_FALSE;
+               }
+
+               if (ct_send(sybct_ptr->cmd)!=CS_SUCCEED) {
+                       ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL);
+                       sybct_ptr->dead = 1;
+                       RETURN_FALSE;
+               }
+
+               /* Use the first result set or succeed/fail status and discard the
+                * others.  Applications really shouldn't be making calls that
+                * return multiple result sets, but if they do then we need to
+                * properly read or cancel them or the connection will become
+                * unusable.
+                */
+               if (ct_results(sybct_ptr->cmd, &restype)!=CS_SUCCEED) {
+                       ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL);
+                       sybct_ptr->dead = 1;
+                       RETURN_FALSE;
+               }
+
+               switch ((int) restype) {
+                       case CS_CMD_FAIL:
+                       default:
+                               status = Q_FAILURE;
+                               break;
+                       case CS_CMD_SUCCEED:
+                       case CS_CMD_DONE: {
+                                       CS_INT row_count;
+                                       if (ct_res_info(sybct_ptr->cmd, CS_ROW_COUNT, &row_count, CS_UNUSED, NULL)==CS_SUCCEED) {
+                                               sybct_ptr->affected_rows = (long)row_count;
+                                       }
+                               }
+                               /* Fall through */
+                       case CS_COMPUTEFMT_RESULT:
+                       case CS_ROWFMT_RESULT:
+                       case CS_DESCRIBE_RESULT:
+                       case CS_MSG_RESULT:
+                               status = Q_SUCCESS;
+                               break;
+                       case CS_COMPUTE_RESULT:
+                       case CS_CURSOR_RESULT:
+                       case CS_PARAM_RESULT:
+                       case CS_ROW_RESULT:
+                       case CS_STATUS_RESULT:
+                               result = _php3_sybct_fetch_result_set(sybct_ptr);
+                               if (result == NULL) {
+                                       ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL);
+                                       sybct_ptr->dead = 1;
+                                       RETURN_FALSE;
+                               }
+                               status = Q_RESULT;
+                               break;
+               }
+
+               /* The only restype we should get now is CS_CMD_DONE, possibly
+                * followed by a CS_STATUS_RESULT/CS_CMD_SUCCEED/CS_CMD_DONE
+                * sequence if the command was a stored procedure call.  But we
+                * still need to read and discard unexpected results.  We might
+                * want to return a failure in this case because the application
+                * won't be getting all the results it asked for.
+                */
+               while ((retcode = ct_results(sybct_ptr->cmd, &restype))==CS_SUCCEED) {
+                       switch ((int) restype) {
+                               case CS_CMD_SUCCEED:
+                               case CS_CMD_DONE:
+                                       break;
+
+                               case CS_CMD_FAIL:
+                                       status = Q_FAILURE;
+                                       break;
+                       
+                               case CS_COMPUTE_RESULT:
+                               case CS_CURSOR_RESULT:
+                               case CS_PARAM_RESULT:
+                               case CS_ROW_RESULT:
+                                       /* Unexpected results, cancel them. */
+                               case CS_STATUS_RESULT:
+                                       ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_CURRENT);
+                                       break;
+                       
+                               default:
+                                       status = Q_FAILURE;
+                                       break;
+                       }
+                       if (status == Q_FAILURE) {
+                               ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL);
+                       }
+               }
+
+               switch (retcode) {
+                       case CS_END_RESULTS:
+                               /* Normal. */
+                               break;
+
+                       case CS_FAIL:
+                               /* Hopefully this either cleans up the connection, or the
+                                * connection ends up marked dead so it will be reopened
+                                * if it is persistent.  We may want to do
+                                * ct_close(CS_FORCE_CLOSE) if ct_cancel() fails; see the
+                                * doc for ct_results()==CS_FAIL.
+                                */
+                               ct_cancel(NULL, sybct_ptr->cmd, CS_CANCEL_ALL);
+                               /* Don't take chances with the vagaries of ct-lib.  Mark it
+                                * dead ourselves.
+                                */
+                               sybct_ptr->dead = 1;
+                       case CS_CANCELED:
+                       default:
+                               status = Q_FAILURE;
+                               break;
+               }
+
+               /* If query completed without deadlock, break out of the loop.
+                * Sometimes deadlock results in failures and sometimes not,
+                * it seems to depend on the server flavor.  But we want to
+                * retry all deadlocks.
+                */
+               if (sybct_ptr->dead || sybct_ptr->deadlock == 0) {
+                       break;
+               }
+
+               /* Get rid of any results we may have fetched.  This happens:
+                * e.g., our result set may be a stored procedure status which
+                * is returned even if the stored procedure deadlocks.  As an
+                * optimization, we could try not to fetch results in known
+                * deadlock conditions, but deadlock is (should be) rare.
+                */
+               if (result != NULL) {
+                       _free_sybct_result(result);
+               }
+       }
+
+       if (status == Q_SUCCESS) {
+               RETURN_TRUE;
+       }
+
+       if (status == Q_FAILURE) {
+               if (result != NULL) {
+                       _free_sybct_result(result);
+               }
+               RETURN_FALSE;
+       }
+
+       return_value->value.lval = php3_list_insert(result,php3_sybct_module.le_result);
+       return_value->type = IS_LONG;
+}
+
+
+void php3_sybct_free_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybct_result_index;
+       sybct_result *result;
+       int type;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &sybct_result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybct_result_index);
+       if (sybct_result_index->value.lval==0) {
+               RETURN_FALSE;
+       }
+       result = (sybct_result *) php3_list_find(sybct_result_index->value.lval,&type);
+       
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",sybct_result_index->value.lval);
+               RETURN_FALSE;
+       }
+       php3_list_delete(sybct_result_index->value.lval);
+       RETURN_TRUE;
+}
+
+
+#if 0
+void php3_sybct_get_last_message(INTERNAL_FUNCTION_PARAMETERS)
+{
+       if (php3_sybct_module.server_message) {
+               RETURN_STRING(php3_sybct_module.server_message,1);
+       }
+}
+#endif 
+
+
+void php3_sybct_num_rows(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result_index;
+       int type,id;
+       sybct_result *result;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result_index);
+       id = result_index->value.lval;
+       
+       result = (sybct_result *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }       
+       
+       return_value->value.lval = result->num_rows;
+       return_value->type = IS_LONG;
+}
+
+
+void php3_sybct_num_fields(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result_index;
+       int type,id;
+       sybct_result *result;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result_index);
+       id = result_index->value.lval;
+       
+       result = (sybct_result *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }       
+       
+       return_value->value.lval = result->num_fields;
+       return_value->type = IS_LONG;
+}
+
+
+void php3_sybct_fetch_row(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybct_result_index;
+       int type,i,id;
+       sybct_result *result;
+       pval field_content;
+
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &sybct_result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybct_result_index);
+       id = sybct_result_index->value.lval;
+       
+       result = (sybct_result *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+       
+       if (result->cur_row >= result->num_rows) {
+               RETURN_FALSE;
+       }
+       
+       array_init(return_value);
+       for (i=0; i<result->num_fields; i++) {
+               field_content = result->data[result->cur_row][i];
+               pval_copy_constructor(&field_content);
+               _php3_hash_index_update(return_value->value.ht, i, (void *) &field_content, sizeof(pval),NULL);
+       }
+       result->cur_row++;
+}
+
+
+static void php3_sybct_fetch_hash(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybct_result_index;
+       sybct_result *result;
+       int type;
+       int i;
+       pval *pval_ptr,tmp;
+       PLS_FETCH();
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &sybct_result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybct_result_index);
+       result = (sybct_result *) php3_list_find(sybct_result_index->value.lval,&type);
+       
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",sybct_result_index->value.lval);
+               RETURN_FALSE;
+       }
+       
+       if (result->cur_row >= result->num_rows) {
+               RETURN_FALSE;
+       }
+       
+       if (array_init(return_value)==FAILURE) {
+               RETURN_FALSE;
+       }
+       
+       for (i=0; i<result->num_fields; i++) {
+               tmp = result->data[result->cur_row][i];
+               pval_copy_constructor(&tmp);
+               if (PG(magic_quotes_runtime) && tmp.type == IS_STRING) {
+                       tmp.value.str.val = _php3_addslashes(tmp.value.str.val,tmp.value.str.len,&tmp.value.str.len,1);
+               }
+               _php3_hash_index_update(return_value->value.ht, i, (void *) &tmp, sizeof(pval), (void **) &pval_ptr);
+               _php3_hash_pointer_update(return_value->value.ht, result->fields[i].name, strlen(result->fields[i].name)+1, pval_ptr);
+       }
+       result->cur_row++;
+}
+
+
+void php3_sybct_fetch_object(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_sybct_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+       if (return_value->type==IS_ARRAY) {
+               return_value->type=IS_OBJECT;
+       }
+}
+
+
+void php3_sybct_fetch_array(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_sybct_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+void php3_sybct_data_seek(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybct_result_index,*offset;
+       int type,id;
+       sybct_result *result;
+
+       if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &sybct_result_index, &offset)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybct_result_index);
+       id = sybct_result_index->value.lval;
+       
+       result = (sybct_result *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+
+       convert_to_long(offset);
+       if (offset->value.lval<0 || offset->value.lval>=result->num_rows) {
+               php3_error(E_WARNING,"Sybase:  Bad row offset");
+               RETURN_FALSE;
+       }
+       
+       result->cur_row = offset->value.lval;
+       RETURN_TRUE;
+}
+
+
+static char *php3_sybct_get_field_name(CS_INT type)
+{
+       switch (type) {
+               case CS_CHAR_TYPE:
+               case CS_VARCHAR_TYPE:
+               case CS_TEXT_TYPE:
+                       return "string";
+                       break;
+               case CS_IMAGE_TYPE:
+                       return "image";
+                       break;
+               case CS_BINARY_TYPE:
+               case CS_VARBINARY_TYPE:
+                       return "blob";
+                       break;
+               case CS_BIT_TYPE:
+                       return "bit";
+                       break;
+               case CS_TINYINT_TYPE:
+               case CS_SMALLINT_TYPE:
+               case CS_INT_TYPE:
+                       return "int";
+                       break;
+               case CS_REAL_TYPE:
+               case CS_FLOAT_TYPE:
+               case CS_NUMERIC_TYPE:
+               case CS_DECIMAL_TYPE:
+                       return "real";
+                       break;
+               case CS_MONEY_TYPE:
+               case CS_MONEY4_TYPE:
+                       return "money";
+                       break;
+               case CS_DATETIME_TYPE:
+               case CS_DATETIME4_TYPE:
+                       return "datetime";
+                       break;
+               default:
+                       return "unknown";
+                       break;
+       }
+}
+
+
+void php3_sybct_fetch_field(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybct_result_index,*offset;
+       int type,id,field_offset;
+       sybct_result *result;
+
+       switch (ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &sybct_result_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       field_offset=-1;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &sybct_result_index, &offset)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(offset);
+                       field_offset = offset->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       convert_to_long(sybct_result_index);
+       id = sybct_result_index->value.lval;
+       
+       result = (sybct_result *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+       
+       if (field_offset==-1) {
+               field_offset = result->cur_field;
+               result->cur_field++;
+       }
+       
+       if (field_offset<0 || field_offset >= result->num_fields) {
+               if (ARG_COUNT(ht)==2) { /* field specified explicitly */
+                       php3_error(E_WARNING,"Sybase:  Bad column offset");
+               }
+               RETURN_FALSE;
+       }
+
+       if (object_init(return_value)==FAILURE) {
+               RETURN_FALSE;
+       }
+       add_property_string(return_value, "name",result->fields[field_offset].name, 1);
+       add_property_long(return_value, "max_length",result->fields[field_offset].max_length);
+       add_property_string(return_value, "column_source",result->fields[field_offset].column_source, 1);
+       add_property_long(return_value, "numeric", result->fields[field_offset].numeric);
+       add_property_string(return_value, "type", php3_sybct_get_field_name(result->fields[field_offset].type), 1);
+}
+
+
+void php3_sybct_field_seek(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybct_result_index,*offset;
+       int type,id,field_offset;
+       sybct_result *result;
+
+       if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &sybct_result_index, &offset)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybct_result_index);
+       id = sybct_result_index->value.lval;
+       
+       result = (sybct_result *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_long(offset);
+       field_offset = offset->value.lval;
+       
+       if (field_offset<0 || field_offset >= result->num_fields) {
+               php3_error(E_WARNING,"Sybase:  Bad column offset");
+               RETURN_FALSE;
+       }
+
+       result->cur_field = field_offset;
+       RETURN_TRUE;
+}
+
+
+void php3_sybct_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *row, *field, *sybct_result_index;
+       int id,type,field_offset=0;
+       sybct_result *result;
+       
+
+       if (ARG_COUNT(ht)!=3 || getParameters(ht, 3, &sybct_result_index, &row, &field)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(sybct_result_index);
+       id = sybct_result_index->value.lval;
+       
+       result = (sybct_result *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_long(row);
+       if (row->value.lval<0 || row->value.lval>=result->num_rows) {
+               php3_error(E_WARNING,"Sybase:  Bad row offset (%d)",row->value.lval);
+               RETURN_FALSE;
+       }
+
+       switch(field->type) {
+               case IS_STRING: {
+                       int i;
+
+                       for (i=0; i<result->num_fields; i++) {
+                               if (!strcasecmp(result->fields[i].name,field->value.str.val)) {
+                                       field_offset = i;
+                                       break;
+                               }
+                       }
+                       if (i>=result->num_fields) { /* no match found */
+                               php3_error(E_WARNING,"Sybase:  %s field not found in result",field->value.str.val);
+                               RETURN_FALSE;
+                       }
+                       break;
+               }
+               default:
+                       convert_to_long(field);
+                       field_offset = field->value.lval;
+                       if (field_offset<0 || field_offset>=result->num_fields) {
+                               php3_error(E_WARNING,"Sybase:  Bad column offset specified");
+                               RETURN_FALSE;
+                       }
+                       break;
+       }
+
+       *return_value = result->data[row->value.lval][field_offset];
+       pval_copy_constructor(return_value);
+}
+
+
+void php3_sybct_affected_rows(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybct_link_index;
+       int id,type;
+       sybct_link *sybct_ptr;
+       CS_INT row_count;
+       
+       switch(ARG_COUNT(ht)) {
+               case 0:
+                       id = php3_sybct_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+                       break;
+               case 1:
+                       if (getParameters(ht, 1, &sybct_link_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(sybct_link_index);
+                       id = sybct_link_index->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       sybct_ptr = (sybct_link *) php3_list_find(id,&type);
+       if (type!=php3_sybct_module.le_link && type!=php3_sybct_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a Sybase link index",id);
+               RETURN_FALSE;
+       }
+
+       return_value->value.lval = sybct_ptr->affected_rows;
+       return_value->type = IS_LONG;
+}
+
+
+void php3_info_sybct(void)
+{
+       char maxp[16],maxl[16];
+       
+       if (php3_sybct_module.max_persistent==-1) {
+               strcpy(maxp,"Unlimited");
+       } else {
+               snprintf(maxp,15,"%ld",php3_sybct_module.max_persistent);
+               maxp[15]=0;
+       }
+       if (php3_sybct_module.max_links==-1) {
+               strcpy(maxl,"Unlimited");
+       } else {
+               snprintf(maxl,15,"%ld",php3_sybct_module.max_links);
+               maxl[15]=0;
+       }
+       php3_printf("<table cellpadding=5>"
+                               "<tr><td>Allow persistent links:</td><td>%s</td></tr>\n"
+                               "<tr><td>Persistent links:</td><td>%d/%s</td></tr>\n"
+                               "<tr><td>Total links:</td><td>%d/%s</td></tr>\n"
+                               "<tr><td>Application name:</td><td>%s</td></tr>\n"
+                               "</table>\n",
+                               (php3_sybct_module.allow_persistent?"Yes":"No"),
+                               php3_sybct_module.num_persistent,maxp,
+                               php3_sybct_module.num_links,maxl,
+                               php3_sybct_module.appname);
+}
+
+
+void php3_sybct_min_client_severity(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *severity;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &severity)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(severity);
+       php3_sybct_module.min_client_severity = severity->value.lval;
+}
+
+
+void php3_sybct_min_server_severity(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *severity;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &severity)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(severity);
+       php3_sybct_module.min_server_severity = severity->value.lval;
+}
+
+
+#endif
diff --git a/ext/sybase/sybase.c b/ext/sybase/sybase.c
new file mode 100644 (file)
index 0000000..11d5fcd
--- /dev/null
@@ -0,0 +1,1258 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Zeev Suraski <zeev@zend.com>                                |
+   +----------------------------------------------------------------------+
+   | php3_sybase_get_column_content_with_type() based on code by:         |
+   |                     Muhammad A Muquit <MA_Muquit@fccc.edu>           |
+   |                     Rasmus Lerdorf <rasmus@lerdorf.on.ca>            |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+
+#ifndef MSVC5
+#include "config.h"
+#endif
+#include "php.h"
+#include "php3_sybase.h"
+#include "ext/standard/php3_standard.h"
+#include "php_globals.h"
+
+#if HAVE_SYBASE
+
+#include <sybfront.h>
+#include <sybdb.h>
+#include <syberror.h>
+
+#if BROKEN_SYBASE_PCONNECTS
+#include "http_log.h"
+#endif
+
+function_entry sybase_functions[] = {
+       {"sybase_connect",                      php3_sybase_connect,                    NULL},
+       {"sybase_pconnect",                     php3_sybase_pconnect,                   NULL},
+       {"sybase_close",                        php3_sybase_close,                              NULL},
+       {"sybase_select_db",            php3_sybase_select_db,                  NULL},
+       {"sybase_query",                        php3_sybase_query,                              NULL},
+       {"sybase_free_result",          php3_sybase_free_result,                NULL},
+       {"sybase_get_last_message",     php3_sybase_get_last_message,   NULL},
+       {"sybase_num_rows",                     php3_sybase_num_rows,                   NULL},
+       {"sybase_num_fields",           php3_sybase_num_fields,                 NULL},
+       {"sybase_fetch_row",            php3_sybase_fetch_row,                  NULL},
+       {"sybase_fetch_array",          php3_sybase_fetch_array,                NULL},
+       {"sybase_fetch_object",         php3_sybase_fetch_object,               NULL},
+       {"sybase_data_seek",            php3_sybase_data_seek,                  NULL},
+       {"sybase_fetch_field",          php3_sybase_fetch_field,                NULL},
+       {"sybase_field_seek",           php3_sybase_field_seek,                 NULL},
+       {"sybase_result",                       php3_sybase_result,                             NULL},
+       {"sybase_min_error_severity",   php3_sybase_min_error_severity,         NULL},
+       {"sybase_min_message_severity", php3_sybase_min_message_severity,       NULL},
+       {"mssql_connect",                       php3_sybase_connect,                    NULL},
+       {"mssql_pconnect",                      php3_sybase_pconnect,                   NULL},
+       {"mssql_close",                         php3_sybase_close,                              NULL},
+       {"mssql_select_db",                     php3_sybase_select_db,                  NULL},
+       {"mssql_query",                         php3_sybase_query,                              NULL},
+       {"mssql_free_result",           php3_sybase_free_result,                NULL},
+       {"mssql_get_last_message",      php3_sybase_get_last_message,   NULL},
+       {"mssql_num_rows",                      php3_sybase_num_rows,                   NULL},
+       {"mssql_num_fields",            php3_sybase_num_fields,                 NULL},
+       {"mssql_fetch_row",                     php3_sybase_fetch_row,                  NULL},
+       {"mssql_fetch_array",           php3_sybase_fetch_array,                NULL},
+       {"mssql_fetch_object",          php3_sybase_fetch_object,               NULL},
+       {"mssql_data_seek",                     php3_sybase_data_seek,                  NULL},
+       {"mssql_fetch_field",           php3_sybase_fetch_field,                NULL},
+       {"mssql_field_seek",            php3_sybase_field_seek,                 NULL},
+       {"mssql_result",                        php3_sybase_result,                             NULL},
+       {"mssql_min_error_severity",    php3_sybase_min_error_severity,         NULL},
+       {"mssql_min_message_severity",  php3_sybase_min_message_severity,       NULL},
+       {NULL, NULL, NULL}
+};
+
+php3_module_entry sybase_module_entry = {
+       "Sybase SQL", sybase_functions, php3_minit_sybase, php3_mshutdown_sybase, php3_rinit_sybase, php3_rshutdown_sybase, php3_info_sybase, STANDARD_MODULE_PROPERTIES
+};
+
+#if COMPILE_DL
+php3_module_entry *get_module() { return &sybase_module_entry; }
+#endif
+
+THREAD_LS sybase_module php3_sybase_module;
+THREAD_LS static HashTable *resource_list, *resource_plist;
+
+
+#define CHECK_LINK(link) { if (link==-1) { php3_error(E_WARNING,"Sybase:  A link to the server could not be established"); RETURN_FALSE; } }
+
+
+static void php3_sybase_get_column_content(sybase_link *sybase_ptr,int offset,pval *result, int column_type);
+
+/* error handler */
+static int php3_sybase_error_handler(DBPROCESS *dbproc,int severity,int dberr,
+                                                                               int oserr,char *dberrstr,char *oserrstr)
+{
+       if (severity >= php3_sybase_module.min_error_severity) {
+               php3_error(E_WARNING,"Sybase error:  %s (severity %d)",dberrstr,severity);
+       }
+       return INT_CANCEL;  
+}
+
+/* message handler */
+static int php3_sybase_message_handler(DBPROCESS *dbproc,DBINT msgno,int msgstate,
+                                                                               int severity,char *msgtext,char *srvname,
+                                                                               char *procname,DBUSMALLINT line)
+{
+       if (severity >= php3_sybase_module.min_message_severity) {
+               php3_error(E_WARNING,"Sybase message:  %s (severity %d)",msgtext,severity);
+       }
+       STR_FREE(php3_sybase_module.server_message);
+       php3_sybase_module.server_message = estrdup(msgtext);
+       return 0;
+}
+
+
+static int _clean_invalid_results(list_entry *le)
+{
+       if (le->type == php3_sybase_module.le_result) {
+               sybase_link *sybase_ptr = ((sybase_result *) le->ptr)->sybase_ptr;
+               
+               if (!sybase_ptr->valid) {
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+
+static void _free_sybase_result(sybase_result *result)
+{
+       int i,j;
+       
+       if (result->data) {
+               for (i=0; i<result->num_rows; i++) {
+                       for (j=0; j<result->num_fields; j++) {
+                               pval_destructor(&result->data[i][j]);
+                       }
+                       efree(result->data[i]);
+               }
+               efree(result->data);
+       }
+       
+       if (result->fields) {
+               for (i=0; i<result->num_fields; i++) {
+                       STR_FREE(result->fields[i].name);
+                       STR_FREE(result->fields[i].column_source);
+               }
+               efree(result->fields);
+       }
+       efree(result);
+}
+
+
+static void _close_sybase_link(sybase_link *sybase_ptr)
+{
+       sybase_ptr->valid = 0;
+       _php3_hash_apply(resource_list,(int (*)(void *))_clean_invalid_results);
+       dbclose(sybase_ptr->link);
+       dbloginfree(sybase_ptr->login);
+       efree(sybase_ptr);
+       php3_sybase_module.num_links--;
+}
+
+
+static void _close_sybase_plink(sybase_link *sybase_ptr)
+{
+       dbclose(sybase_ptr->link);
+       dbloginfree(sybase_ptr->login);
+       free(sybase_ptr);
+       php3_sybase_module.num_persistent--;
+       php3_sybase_module.num_links--;
+}
+
+
+int php3_minit_sybase(INIT_FUNC_ARGS)
+{
+       char *interface_file;
+
+       if (dbinit()==FAIL) {
+               return FAILURE;
+       }
+       dberrhandle((EHANDLEFUNC) php3_sybase_error_handler);
+       dbmsghandle((MHANDLEFUNC) php3_sybase_message_handler);
+
+       if (cfg_get_string("sybase.interface_file",&interface_file)==SUCCESS) {
+               dbsetifile(interface_file);
+       }
+       if (cfg_get_long("sybase.allow_persistent",&php3_sybase_module.allow_persistent)==FAILURE) {
+               php3_sybase_module.allow_persistent=1;
+       }
+       if (cfg_get_long("sybase.max_persistent",&php3_sybase_module.max_persistent)==FAILURE) {
+               php3_sybase_module.max_persistent=-1;
+       }
+       if (cfg_get_long("sybase.max_links",&php3_sybase_module.max_links)==FAILURE) {
+               php3_sybase_module.max_links=-1;
+       }
+       if (cfg_get_long("sybase.min_error_severity",&php3_sybase_module.cfg_min_error_severity)==FAILURE) {
+               php3_sybase_module.cfg_min_error_severity=10;
+       }
+       if (cfg_get_long("sybase.min_message_severity",&php3_sybase_module.cfg_min_message_severity)==FAILURE) {
+               php3_sybase_module.cfg_min_message_severity=10;
+       }
+       if (cfg_get_long("sybase.compatability_mode",&php3_sybase_module.compatability_mode)==FAILURE) {
+               php3_sybase_module.compatability_mode = 0;
+       }
+       
+       php3_sybase_module.num_persistent=0;
+       php3_sybase_module.le_link = register_list_destructors(_close_sybase_link,NULL);
+       php3_sybase_module.le_plink = register_list_destructors(NULL,_close_sybase_plink);
+       php3_sybase_module.le_result = register_list_destructors(_free_sybase_result,NULL);
+       
+       return SUCCESS;
+}
+
+
+int php3_rinit_sybase(INIT_FUNC_ARGS)
+{
+       php3_sybase_module.default_link=-1;
+       php3_sybase_module.num_links = php3_sybase_module.num_persistent;
+       php3_sybase_module.appname = estrndup("PHP 3.0",7);
+       php3_sybase_module.server_message = empty_string;
+       php3_sybase_module.min_error_severity = php3_sybase_module.cfg_min_error_severity;
+       php3_sybase_module.min_message_severity = php3_sybase_module.cfg_min_message_severity;
+       return SUCCESS;
+}
+
+int php3_mshutdown_sybase(SHUTDOWN_FUNC_ARGS)
+{
+       dbexit();
+       return SUCCESS;
+}
+
+int php3_rshutdown_sybase(SHUTDOWN_FUNC_ARGS)
+{
+       efree(php3_sybase_module.appname);
+       STR_FREE(php3_sybase_module.server_message);
+       return SUCCESS;
+}
+
+static void php3_sybase_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent)
+{
+       char *user,*passwd,*host;
+       char *hashed_details;
+       int hashed_details_length;
+       sybase_link sybase,*sybase_ptr;
+
+       resource_list = list;
+       resource_plist = plist;
+               
+       switch(ARG_COUNT(ht)) {
+               case 0: /* defaults */
+                       host=user=passwd=NULL;
+                       hashed_details_length=6+3;
+                       hashed_details = (char *) emalloc(hashed_details_length+1);
+                       strcpy(hashed_details,"sybase___");
+                       break;
+               case 1: {
+                               pval *yyhost;
+                               
+                               if (getParameters(ht, 1, &yyhost)==FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               host = yyhost->value.str.val;
+                               user=passwd=NULL;
+                               hashed_details_length = yyhost->value.str.len+6+3;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"sybase_%s__",yyhost->value.str.val);
+                       }
+                       break;
+               case 2: {
+                               pval *yyhost,*yyuser;
+                               
+                               if (getParameters(ht, 2, &yyhost, &yyuser)==FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               convert_to_string(yyuser);
+                               host = yyhost->value.str.val;
+                               user = yyuser->value.str.val;
+                               passwd=NULL;
+                               hashed_details_length = yyhost->value.str.len+yyuser->value.str.len+6+3;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"sybase_%s_%s_",yyhost->value.str.val,yyuser->value.str.val);
+                       }
+                       break;
+               case 3: {
+                               pval *yyhost,*yyuser,*yypasswd;
+                       
+                               if (getParameters(ht, 3, &yyhost, &yyuser, &yypasswd) == FAILURE) {
+                                       RETURN_FALSE;
+                               }
+                               convert_to_string(yyhost);
+                               convert_to_string(yyuser);
+                               convert_to_string(yypasswd);
+                               host = yyhost->value.str.val;
+                               user = yyuser->value.str.val;
+                               passwd = yypasswd->value.str.val;
+                               hashed_details_length = yyhost->value.str.len+yyuser->value.str.len+yypasswd->value.str.len+6+3;
+                               hashed_details = (char *) emalloc(hashed_details_length+1);
+                               sprintf(hashed_details,"sybase_%s_%s_%s",yyhost->value.str.val,yyuser->value.str.val,yypasswd->value.str.val); /* SAFE */
+                       }
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+
+       /* set a DBLOGIN record */      
+       if ((sybase.login=dblogin())==NULL) {
+               php3_error(E_WARNING,"Sybase:  Unable to allocate login record");
+               RETURN_FALSE;
+       }
+       
+       if (user) {
+               DBSETLUSER(sybase.login,user);
+       }
+       if (passwd) {
+               DBSETLPWD(sybase.login,passwd);
+       }
+       DBSETLAPP(sybase.login,php3_sybase_module.appname);
+       sybase.valid = 1;
+
+       if (!php3_sybase_module.allow_persistent) {
+               persistent=0;
+       }
+       if (persistent) {
+               list_entry *le;
+
+               /* try to find if we already have this link in our persistent list */
+               if (_php3_hash_find(plist, hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) {  /* we don't */
+                       list_entry new_le;
+
+                       if (php3_sybase_module.max_links!=-1 && php3_sybase_module.num_links>=php3_sybase_module.max_links) {
+                               php3_error(E_WARNING,"Sybase:  Too many open links (%d)",php3_sybase_module.num_links);
+                               efree(hashed_details);
+                               dbloginfree(sybase.login);
+                               RETURN_FALSE;
+                       }
+                       if (php3_sybase_module.max_persistent!=-1 && php3_sybase_module.num_persistent>=php3_sybase_module.max_persistent) {
+                               php3_error(E_WARNING,"Sybase:  Too many open persistent links (%d)",php3_sybase_module.num_persistent);
+                               efree(hashed_details);
+                               dbloginfree(sybase.login);
+                               RETURN_FALSE;
+                       }
+                       /* create the link */
+                       if ((sybase.link=dbopen(sybase.login,host))==FAIL) {
+                               /*php3_error(E_WARNING,"Sybase:  Unable to connect to server:  %s",sybase_error(sybase));*/
+                               efree(hashed_details);
+                               dbloginfree(sybase.login);
+                               RETURN_FALSE;
+                       }
+
+                       if (dbsetopt(sybase.link,DBBUFFER,"2",-1)==FAIL) {
+                               efree(hashed_details);
+                               dbloginfree(sybase.login);
+                               dbclose(sybase.link);
+                               RETURN_FALSE;
+                       }
+
+                       /* hash it up */
+                       sybase_ptr = (sybase_link *) malloc(sizeof(sybase_link));
+                       memcpy(sybase_ptr,&sybase,sizeof(sybase_link));
+                       new_le.type = php3_sybase_module.le_plink;
+                       new_le.ptr = sybase_ptr;
+                       if (_php3_hash_update(plist, hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(list_entry),NULL)==FAILURE) {
+                               free(sybase_ptr);
+                               efree(hashed_details);
+                               dbloginfree(sybase.login);
+                               RETURN_FALSE;
+                       }
+                       php3_sybase_module.num_persistent++;
+                       php3_sybase_module.num_links++;
+               } else {  /* we do */
+                       if (le->type != php3_sybase_module.le_plink) {
+#if BROKEN_SYBASE_PCONNECTS
+                               log_error("PHP/Sybase:  Hashed persistent link is not a Sybase link!",php3_rqst->server);
+#endif
+                               php3_error(E_WARNING,"Sybase:  Hashed persistent link is not a Sybase link!");
+                               RETURN_FALSE;
+                       }
+                       
+                       sybase_ptr = (sybase_link *) le->ptr;
+                       /* test that the link hasn't died */
+                       if (DBDEAD(sybase_ptr->link)==TRUE) {
+#if BROKEN_SYBASE_PCONNECTS
+                               log_error("PHP/Sybase:  Persistent link died, trying to reconnect...",php3_rqst->server);
+#endif
+                               if ((sybase_ptr->link=dbopen(sybase_ptr->login,host))==FAIL) {
+#if BROKEN_SYBASE_PCONNECTS
+                                       log_error("PHP/Sybase:  Unable to reconnect!",php3_rqst->server);
+#endif
+                                       /*php3_error(E_WARNING,"Sybase:  Link to server lost, unable to reconnect");*/
+                                       _php3_hash_del(plist, hashed_details, hashed_details_length+1);
+                                       efree(hashed_details);
+                                       RETURN_FALSE;
+                               }
+#if BROKEN_SYBASE_PCONNECTS
+                               log_error("PHP/Sybase:  Reconnect successful!",php3_rqst->server);
+#endif
+                               if (dbsetopt(sybase_ptr->link,DBBUFFER,"2",-1)==FAIL) {
+#if BROKEN_SYBASE_PCONNECTS
+                                       log_error("PHP/Sybase:  Unable to set required options",php3_rqst->server);
+#endif
+                                       _php3_hash_del(plist, hashed_details, hashed_details_length+1);
+                                       efree(hashed_details);
+                                       RETURN_FALSE;
+                               }
+                       }
+               }
+               return_value->value.lval = php3_list_insert(sybase_ptr,php3_sybase_module.le_plink);
+               return_value->type = IS_LONG;
+       } else { /* non persistent */
+               list_entry *index_ptr,new_index_ptr;
+               
+               /* first we check the hash for the hashed_details key.  if it exists,
+                * it should point us to the right offset where the actual sybase link sits.
+                * if it doesn't, open a new sybase link, add it to the resource list,
+                * and add a pointer to it with hashed_details as the key.
+                */
+               if (_php3_hash_find(list,hashed_details,hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
+                       int type,link;
+                       void *ptr;
+
+                       if (index_ptr->type != le_index_ptr) {
+                               RETURN_FALSE;
+                       }
+                       link = (int) index_ptr->ptr;
+                       ptr = php3_list_find(link,&type);   /* check if the link is still there */
+                       if (ptr && (type==php3_sybase_module.le_link || type==php3_sybase_module.le_plink)) {
+                               return_value->value.lval = php3_sybase_module.default_link = link;
+                               return_value->type = IS_LONG;
+                               efree(hashed_details);
+                               return;
+                       } else {
+                               _php3_hash_del(list,hashed_details,hashed_details_length+1);
+                       }
+               }
+               if (php3_sybase_module.max_links!=-1 && php3_sybase_module.num_links>=php3_sybase_module.max_links) {
+                       php3_error(E_WARNING,"Sybase:  Too many open links (%d)",php3_sybase_module.num_links);
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+               
+               if ((sybase.link=dbopen(sybase.login,host))==NULL) {
+                       /*php3_error(E_WARNING,"Sybase:  Unable to connect to server:  %s",sybase_error(sybase));*/
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+
+               if (dbsetopt(sybase.link,DBBUFFER,"2",-1)==FAIL) {
+                       efree(hashed_details);
+                       dbloginfree(sybase.login);
+                       dbclose(sybase.link);
+                       RETURN_FALSE;
+               }
+               
+               /* add it to the list */
+               sybase_ptr = (sybase_link *) emalloc(sizeof(sybase_link));
+               memcpy(sybase_ptr,&sybase,sizeof(sybase_link));
+               return_value->value.lval = php3_list_insert(sybase_ptr,php3_sybase_module.le_link);
+               return_value->type = IS_LONG;
+               
+               /* add it to the hash */
+               new_index_ptr.ptr = (void *) return_value->value.lval;
+               new_index_ptr.type = le_index_ptr;
+               if (_php3_hash_update(list,hashed_details,hashed_details_length+1,(void *) &new_index_ptr, sizeof(list_entry),NULL)==FAILURE) {
+                       efree(hashed_details);
+                       RETURN_FALSE;
+               }
+               php3_sybase_module.num_links++;
+       }
+       efree(hashed_details);
+       php3_sybase_module.default_link=return_value->value.lval;
+}
+
+
+static int php3_sybase_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
+{
+       if (php3_sybase_module.default_link==-1) { /* no link opened yet, implicitly open one */
+               HashTable dummy;
+
+               _php3_hash_init(&dummy,0,NULL,NULL,0);
+               php3_sybase_do_connect(&dummy,return_value,list,plist,0);
+               _php3_hash_destroy(&dummy);
+       }
+       return php3_sybase_module.default_link;
+}
+
+
+void php3_sybase_connect(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_sybase_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,0);
+}
+
+void php3_sybase_pconnect(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_sybase_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU,1);
+}
+
+
+void php3_sybase_close(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybase_link_index;
+       int id,type;
+       
+       switch (ARG_COUNT(ht)) {
+               case 0:
+                       id = php3_sybase_module.default_link;
+                       break;
+               case 1:
+                       if (getParameters(ht, 1, &sybase_link_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(sybase_link_index);
+                       id = sybase_link_index->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_link && type!=php3_sybase_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a Sybase link index",id);
+               RETURN_FALSE;
+       }
+       
+       php3_list_delete(id);
+       RETURN_TRUE;
+}
+       
+
+void php3_sybase_select_db(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *db,*sybase_link_index;
+       int id,type;
+       sybase_link  *sybase_ptr;
+       
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &db)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       id = php3_sybase_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &db, &sybase_link_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(sybase_link_index);
+                       id = sybase_link_index->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       CHECK_LINK(id);
+       
+       sybase_ptr = (sybase_link *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_link && type!=php3_sybase_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a Sybase link index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_string(db);
+       
+       if (dbuse(sybase_ptr->link,db->value.str.val)==FAIL) {
+               /*php3_error(E_WARNING,"Sybase:  Unable to select database:  %s",sybase_error(sybase));*/
+               RETURN_FALSE;
+       } else {
+               RETURN_TRUE;
+       }
+}
+
+
+static void php3_sybase_get_column_content(sybase_link *sybase_ptr,int offset,pval *result, int column_type)
+{
+       if (dbdatlen(sybase_ptr->link,offset) == 0) {
+               var_reset(result);
+               return;
+       }
+
+       switch (column_type)
+       {
+               case SYBINT2:
+               case SYBINT4: { 
+                       result->value.lval = (long) anyintcol(offset);
+                       result->type = IS_LONG;
+                       break;
+               }
+               case SYBCHAR:
+               case SYBTEXT: {
+                       int length;
+                       char *data = charcol(offset);
+
+                       length=dbdatlen(sybase_ptr->link,offset);
+                       while (length>0 && charcol(offset)[length-1] == ' ') { /* nuke trailing whitespace */
+                               length--;
+                       }
+                       result->value.str.val = estrndup(data,length);
+                       result->value.str.len = length;
+                       result->type = IS_STRING;
+                       break;
+               }
+               /*case SYBFLT8:*/
+               case SYBREAL: {
+                       result->value.dval = (double) floatcol(offset);
+                       result->type = IS_DOUBLE;
+                       break;
+               }
+               default: {
+                       if (dbwillconvert(coltype(offset),SYBCHAR)) {
+                               char *res_buf;
+                               int res_length = dbdatlen(sybase_ptr->link,offset);
+                               register char *p;
+                       
+                               switch (coltype(offset)) {
+                                       case SYBBINARY:
+                                       case SYBVARBINARY:
+                                       case SYBCHAR:
+                                       case SYBVARCHAR:
+                                       case SYBTEXT:
+                                       case SYBIMAGE:
+                                               break;
+                                       default:
+                                               /* take no chances, no telling how big the result would really be */
+                                               res_length += 20;
+                                               break;
+                               }
+
+                               res_buf = (char *) emalloc(res_length+1);
+                               dbconvert(NULL,coltype(offset),dbdata(sybase_ptr->link,offset), res_length,SYBCHAR,res_buf,-1);
+               
+                               /* get rid of trailing spaces */
+                               p = res_buf + res_length;
+                               while (*p == ' ') {
+                                       p--;
+                                       res_length--;
+                               }
+                               *(++p) = 0; /* put a trailing NULL */
+               
+                               result->value.str.len = res_length;
+                               result->value.str.val = res_buf;
+                               result->type = IS_STRING;
+                       } else {
+                               php3_error(E_WARNING,"Sybase:  column %d has unknown data type (%d)", offset, coltype(offset));
+                               var_reset(result);
+                       }
+               }
+       }
+}
+
+
+void php3_sybase_query(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *query,*sybase_link_index;
+       int id,type,retvalue;
+       sybase_link *sybase_ptr;
+       sybase_result *result;
+       int num_fields;
+       int blocks_initialized=1;
+       int i,j;
+       int *column_types;
+
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &query)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       id = php3_sybase_module.default_link;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &query, &sybase_link_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(sybase_link_index);
+                       id = sybase_link_index->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       sybase_ptr = (sybase_link *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_link && type!=php3_sybase_module.le_plink) {
+               php3_error(E_WARNING,"%d is not a Sybase link index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_string(query);
+       if (dbcmd(sybase_ptr->link,query->value.str.val)==FAIL) {
+               /*php3_error(E_WARNING,"Sybase:  Unable to set query");*/
+               RETURN_FALSE;
+       }
+       if (dbsqlexec(sybase_ptr->link)==FAIL || dbresults(sybase_ptr->link)==FAIL) {
+               /*php3_error(E_WARNING,"Sybase:  Query failed");*/
+               RETURN_FALSE;
+       }
+       
+       /* The following is more or less the equivalent of mysql_store_result().
+        * fetch all rows from the server into the row buffer, thus:
+        * 1)  Being able to fire up another query without explicitly reading all rows
+        * 2)  Having numrows accessible
+        */
+       
+       retvalue=dbnextrow(sybase_ptr->link);
+       
+       if (retvalue==FAIL) {
+               RETURN_FALSE;
+       }
+
+       num_fields = dbnumcols(sybase_ptr->link);
+       if (num_fields<=0) {
+               RETURN_TRUE;
+       }
+       
+       column_types = (int *) emalloc(sizeof(int) * num_fields);
+       for (i=0; i<num_fields; i++) {
+               column_types[i] = coltype(i+1);
+       }
+       
+       result = (sybase_result *) emalloc(sizeof(sybase_result));
+       result->data = (pval **) emalloc(sizeof(pval *)*SYBASE_ROWS_BLOCK);
+       result->sybase_ptr = sybase_ptr;
+       result->cur_field=result->cur_row=result->num_rows=0;
+       result->num_fields = num_fields;
+
+       i=0;
+       while (retvalue!=FAIL && retvalue!=NO_MORE_ROWS) {
+               result->num_rows++;
+               if (result->num_rows > blocks_initialized*SYBASE_ROWS_BLOCK) {
+                       result->data = (pval **) erealloc(result->data,sizeof(pval *)*SYBASE_ROWS_BLOCK*(++blocks_initialized));
+               }
+               result->data[i] = (pval *) emalloc(sizeof(pval)*num_fields);
+               for (j=1; j<=num_fields; j++) {
+                       php3_sybase_get_column_content(sybase_ptr, j, &result->data[i][j-1], column_types[j-1]);
+                       if (!php3_sybase_module.compatability_mode) {
+                               convert_to_string(&result->data[i][j-1]);
+                       }
+               }
+               retvalue=dbnextrow(sybase_ptr->link);
+               dbclrbuf(sybase_ptr->link,DBLASTROW(sybase_ptr->link)-1); 
+               i++;
+       }
+       result->num_rows = DBCOUNT(sybase_ptr->link);
+       
+       result->fields = (sybase_field *) emalloc(sizeof(sybase_field)*num_fields);
+       j=0;
+       for (i=0; i<num_fields; i++) {
+               char *fname = dbcolname(sybase_ptr->link,i+1);
+               char computed_buf[16];
+               
+               if (*fname) {
+                       result->fields[i].name = estrdup(fname);
+               } else {
+                       if (j>0) {
+                               snprintf(computed_buf,16,"computed%d",j);
+                       } else {
+                               strcpy(computed_buf,"computed");
+                       }
+                       result->fields[i].name = estrdup(computed_buf);
+                       j++;
+               }
+               result->fields[i].max_length = dbcollen(sybase_ptr->link,i+1);
+               result->fields[i].column_source = estrdup(dbcolsource(sybase_ptr->link,i+1));
+               if (!result->fields[i].column_source) {
+                       result->fields[i].column_source = empty_string;
+               }
+               result->fields[i].type = column_types[i];
+               /* set numeric flag */
+               switch (column_types[i]) {
+                       case SYBINT2:
+                       case SYBINT4:
+                       case SYBFLT8:
+                       case SYBREAL:
+                               result->fields[i].numeric = 1;
+                               break;
+                       case SYBCHAR:
+                       case SYBTEXT:
+                       default:
+                               result->fields[i].numeric = 0;
+                               break;
+               }
+       }
+       efree(column_types);
+       return_value->value.lval = php3_list_insert(result,php3_sybase_module.le_result);
+       return_value->type = IS_LONG;
+}
+
+                        
+void php3_sybase_free_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybase_result_index;
+       sybase_result *result;
+       int type;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &sybase_result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybase_result_index);
+       if (sybase_result_index->value.lval==0) {
+               RETURN_FALSE;
+       }
+       result = (sybase_result *) php3_list_find(sybase_result_index->value.lval,&type);
+       
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",sybase_result_index->value.lval);
+               RETURN_FALSE;
+       }
+       php3_list_delete(sybase_result_index->value.lval);
+       RETURN_TRUE;
+}
+
+
+void php3_sybase_get_last_message(INTERNAL_FUNCTION_PARAMETERS)
+{
+       RETURN_STRING(php3_sybase_module.server_message,1);
+}
+
+
+void php3_sybase_num_rows(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result_index;
+       int type,id;
+       sybase_result *result;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result_index);
+       id = result_index->value.lval;
+       
+       result = (sybase_result *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }       
+       
+       return_value->value.lval = result->num_rows;
+       return_value->type = IS_LONG;
+}
+
+
+void php3_sybase_num_fields(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *result_index;
+       int type,id;
+       sybase_result *result;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(result_index);
+       id = result_index->value.lval;
+       
+       result = (sybase_result *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }       
+       
+       return_value->value.lval = result->num_fields;
+       return_value->type = IS_LONG;
+}
+
+
+void php3_sybase_fetch_row(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybase_result_index;
+       int type,i,id;
+       sybase_result *result;
+       pval field_content;
+
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &sybase_result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybase_result_index);
+       id = sybase_result_index->value.lval;
+       
+       result = (sybase_result *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+       
+       if (result->cur_row >= result->num_rows) {
+               RETURN_FALSE;
+       }
+       
+       array_init(return_value);
+       for (i=0; i<result->num_fields; i++) {
+               field_content = result->data[result->cur_row][i];
+               pval_copy_constructor(&field_content);
+               _php3_hash_index_update(return_value->value.ht, i, (void *) &field_content, sizeof(pval),NULL);
+       }
+       result->cur_row++;
+}
+
+
+static void php3_sybase_fetch_hash(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybase_result_index;
+       sybase_result *result;
+       int type;
+       int i;
+       pval *pval_ptr,tmp;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &sybase_result_index)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybase_result_index);
+       result = (sybase_result *) php3_list_find(sybase_result_index->value.lval,&type);
+       
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",sybase_result_index->value.lval);
+               RETURN_FALSE;
+       }
+       
+       if (result->cur_row >= result->num_rows) {
+               RETURN_FALSE;
+       }
+       
+       if (array_init(return_value)==FAILURE) {
+               RETURN_FALSE;
+       }
+       
+       for (i=0; i<result->num_fields; i++) {
+               tmp = result->data[result->cur_row][i];
+               pval_copy_constructor(&tmp);
+               if (PG(magic_quotes_runtime) && tmp.type == IS_STRING) {
+                       tmp.value.str.val = _php3_addslashes(tmp.value.str.val,tmp.value.str.len,&tmp.value.str.len,1);
+               }
+               _php3_hash_index_update(return_value->value.ht, i, (void *) &tmp, sizeof(pval), (void **) &pval_ptr);
+               _php3_hash_pointer_update(return_value->value.ht, result->fields[i].name, strlen(result->fields[i].name)+1, pval_ptr);
+       }
+       result->cur_row++;
+}
+
+
+void php3_sybase_fetch_object(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_sybase_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+       if (return_value->type==IS_ARRAY) {
+               return_value->type=IS_OBJECT;
+       }
+}
+
+
+void php3_sybase_fetch_array(INTERNAL_FUNCTION_PARAMETERS)
+{
+       php3_sybase_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+void php3_sybase_data_seek(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybase_result_index,*offset;
+       int type,id;
+       sybase_result *result;
+
+       if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &sybase_result_index, &offset)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybase_result_index);
+       id = sybase_result_index->value.lval;
+       
+       result = (sybase_result *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+
+       convert_to_long(offset);
+       if (offset->value.lval<0 || offset->value.lval>=result->num_rows) {
+               php3_error(E_WARNING,"Sybase:  Bad row offset");
+               RETURN_FALSE;
+       }
+       
+       result->cur_row = offset->value.lval;
+       RETURN_TRUE;
+}
+
+
+static char *php3_sybase_get_field_name(int type)
+{
+       switch (type) {
+               case SYBBINARY:
+               case SYBVARBINARY:
+                       return "blob";
+                       break;
+               case SYBCHAR:
+               case SYBVARCHAR:
+               case SYBTEXT:
+                       return "string";
+               case SYBDATETIME:
+               case SYBDATETIME4:
+               case SYBDATETIMN:
+                       return "datetime";
+                       break;
+               case SYBDECIMAL:
+               case SYBFLT8:
+               case SYBFLTN:
+               case SYBREAL:
+               case SYBNUMERIC:
+                       return "real";
+                       break;
+               case SYBINT1:
+               case SYBINT2:
+               case SYBINT4:
+               case SYBINTN:
+                       return "int";
+                       break;
+               case SYBMONEY:
+               case SYBMONEY4:
+               case SYBMONEYN:
+                       return "money";
+                       break;
+               case SYBBIT:
+                       return "bit";
+                       break;
+               case SYBIMAGE:
+                       return "image";
+                       break;
+               default:
+                       return "unknown";
+                       break;
+       }
+}
+
+
+void php3_sybase_fetch_field(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybase_result_index,*offset;
+       int type,id,field_offset;
+       sybase_result *result;
+
+       switch (ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &sybase_result_index)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       field_offset=-1;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &sybase_result_index, &offset)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(offset);
+                       field_offset = offset->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+       
+       convert_to_long(sybase_result_index);
+       id = sybase_result_index->value.lval;
+       
+       result = (sybase_result *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+       
+       if (field_offset==-1) {
+               field_offset = result->cur_field;
+               result->cur_field++;
+       }
+       
+       if (field_offset<0 || field_offset >= result->num_fields) {
+               if (ARG_COUNT(ht)==2) { /* field specified explicitly */
+                       php3_error(E_WARNING,"Sybase:  Bad column offset");
+               }
+               RETURN_FALSE;
+       }
+
+       if (object_init(return_value)==FAILURE) {
+               RETURN_FALSE;
+       }
+       add_property_string(return_value, "name",result->fields[field_offset].name, 1);
+       add_property_long(return_value, "max_length",result->fields[field_offset].max_length);
+       add_property_string(return_value, "column_source",result->fields[field_offset].column_source, 1);
+       add_property_long(return_value, "numeric", result->fields[field_offset].numeric);
+       add_property_string(return_value, "type", php3_sybase_get_field_name(result->fields[field_offset].type), 1);
+}
+
+void php3_sybase_field_seek(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *sybase_result_index,*offset;
+       int type,id,field_offset;
+       sybase_result *result;
+
+       if (ARG_COUNT(ht)!=2 || getParameters(ht, 2, &sybase_result_index, &offset)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       
+       convert_to_long(sybase_result_index);
+       id = sybase_result_index->value.lval;
+       
+       result = (sybase_result *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_long(offset);
+       field_offset = offset->value.lval;
+       
+       if (field_offset<0 || field_offset >= result->num_fields) {
+               php3_error(E_WARNING,"Sybase:  Bad column offset");
+               RETURN_FALSE;
+       }
+
+       result->cur_field = field_offset;
+       RETURN_TRUE;
+}
+
+
+void php3_sybase_result(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *row, *field, *sybase_result_index;
+       int id,type,field_offset=0;
+       sybase_result *result;
+       
+
+       if (ARG_COUNT(ht)!=3 || getParameters(ht, 3, &sybase_result_index, &row, &field)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(sybase_result_index);
+       id = sybase_result_index->value.lval;
+       
+       result = (sybase_result *) php3_list_find(id,&type);
+       if (type!=php3_sybase_module.le_result) {
+               php3_error(E_WARNING,"%d is not a Sybase result index",id);
+               RETURN_FALSE;
+       }
+       
+       convert_to_long(row);
+       if (row->value.lval<0 || row->value.lval>=result->num_rows) {
+               php3_error(E_WARNING,"Sybase:  Bad row offset (%d)",row->value.lval);
+               RETURN_FALSE;
+       }
+
+       switch(field->type) {
+               case IS_STRING: {
+                       int i;
+
+                       for (i=0; i<result->num_fields; i++) {
+                               if (!strcasecmp(result->fields[i].name,field->value.str.val)) {
+                                       field_offset = i;
+                                       break;
+                               }
+                       }
+                       if (i>=result->num_fields) { /* no match found */
+                               php3_error(E_WARNING,"Sybase:  %s field not found in result",field->value.str.val);
+                               RETURN_FALSE;
+                       }
+                       break;
+               }
+               default:
+                       convert_to_long(field);
+                       field_offset = field->value.lval;
+                       if (field_offset<0 || field_offset>=result->num_fields) {
+                               php3_error(E_WARNING,"Sybase:  Bad column offset specified");
+                               RETURN_FALSE;
+                       }
+                       break;
+       }
+
+       *return_value = result->data[row->value.lval][field_offset];
+       pval_copy_constructor(return_value);
+}
+
+
+void php3_info_sybase(void)
+{
+       char maxp[16],maxl[16];
+       
+       if (php3_sybase_module.max_persistent==-1) {
+               strcpy(maxp,"Unlimited");
+       } else {
+               snprintf(maxp,15,"%ld",php3_sybase_module.max_persistent);
+               maxp[15]=0;
+       }
+       if (php3_sybase_module.max_links==-1) {
+               strcpy(maxl,"Unlimited");
+       } else {
+               snprintf(maxl,15,"%ld",php3_sybase_module.max_links);
+               maxl[15]=0;
+       }
+       php3_printf("<table cellpadding=5>"
+                               "<tr><td>Allow persistent links:</td><td>%s</td></tr>\n"
+                               "<tr><td>Persistent links:</td><td>%d/%s</td></tr>\n"
+                               "<tr><td>Total links:</td><td>%d/%s</td></tr>\n"
+                               "<tr><td>Application name:</td><td>%s</td></tr>\n"
+                               "<tr><td valign=\"top\" width=\"20%%\">Client API information:</td><td><pre>%s</pre></td></tr>\n"
+                               "</table>\n",
+                               (php3_sybase_module.allow_persistent?"Yes":"No"),
+                               php3_sybase_module.num_persistent,maxp,
+                               php3_sybase_module.num_links,maxl,
+                               php3_sybase_module.appname,
+                               dbversion());
+}
+
+
+void php3_sybase_min_error_severity(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *severity;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &severity)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(severity);
+       php3_sybase_module.min_error_severity = severity->value.lval;
+}
+
+
+void php3_sybase_min_message_severity(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *severity;
+       
+       if (ARG_COUNT(ht)!=1 || getParameters(ht, 1, &severity)==FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(severity);
+       php3_sybase_module.min_message_severity = severity->value.lval;
+}
+
+#endif
diff --git a/ext/sysvsem/Makefile.am b/ext/sysvsem/Makefile.am
new file mode 100644 (file)
index 0000000..7ed09a0
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_sysvsem.a
+libphpext_sysvsem_a_SOURCES=sysvsem.c
+
diff --git a/ext/sysvsem/Makefile.in b/ext/sysvsem/Makefile.in
new file mode 100644 (file)
index 0000000..8563cb6
--- /dev/null
@@ -0,0 +1,270 @@
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id$
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DISTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+APACHE_INCLUDE = @APACHE_INCLUDE@
+APACHE_TARGET = @APACHE_TARGET@
+APXS = @APXS@
+APXS_LDFLAGS = @APXS_LDFLAGS@
+BINNAME = @BINNAME@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CFLAGS_SHLIB = @CFLAGS_SHLIB@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+EXTINFO_DEPS = @EXTINFO_DEPS@
+EXTRA_LIBS = @EXTRA_LIBS@
+EXT_LIBS = @EXT_LIBS@
+EXT_SUBDIRS = @EXT_SUBDIRS@
+FHTTPD_LIB = @FHTTPD_LIB@
+FHTTPD_TARGET = @FHTTPD_TARGET@
+HSREGEX = @HSREGEX@
+INSTALL_IT = @INSTALL_IT@
+LDFLAGS_SHLIB = @LDFLAGS_SHLIB@
+LDFLAGS_SHLIB_EXPORT = @LDFLAGS_SHLIB_EXPORT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+PERL_PATH = @PERL_PATH@
+PHP_BUILD_DATE = @PHP_BUILD_DATE@
+PHP_DEBUG = @PHP_DEBUG@
+PHP_LIBS = @PHP_LIBS@
+PHP_VERSION = @PHP_VERSION@
+PROG_SENDMAIL = @PROG_SENDMAIL@
+RANLIB = @RANLIB@
+RDYNAMIC_LFLAGS = @RDYNAMIC_LFLAGS@
+REGEX_LIB = @REGEX_LIB@
+STRONGHOLD = @STRONGHOLD@
+VERSION = @VERSION@
+WARNING_LEVEL = @WARNING_LEVEL@
+YACC = @YACC@
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_sysvsem.a
+libphpext_sysvsem_a_SOURCES=sysvsem.c
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libphpext_sysvsem_a_LIBADD = 
+libphpext_sysvsem_a_OBJECTS =  sysvsem.o
+AR = ar
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(libphpext_sysvsem_a_SOURCES)
+OBJECTS = $(libphpext_sysvsem_a_OBJECTS)
+
+all: Makefile $(LIBRARIES)
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: @MAINT@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps ext/sysvsem/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+       $(COMPILE) -c $<
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libphpext_sysvsem.a: $(libphpext_sysvsem_a_OBJECTS) $(libphpext_sysvsem_a_DEPENDENCIES)
+       -rm -f libphpext_sysvsem.a
+       $(AR) cru libphpext_sysvsem.a $(libphpext_sysvsem_a_OBJECTS) $(libphpext_sysvsem_a_LIBADD)
+       $(RANLIB) libphpext_sysvsem.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = ext/sysvsem
+
+distdir: $(DISTFILES)
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
+       done
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
+install-strip:
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f Makefile $(DISTCLEANFILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-generic
+
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
+               mostlyclean
+
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-generic clean
+       -rm -f config.status
+
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-generic distclean
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-exec install-data install uninstall all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ext/sysvsem/config.h.stub b/ext/sysvsem/config.h.stub
new file mode 100644 (file)
index 0000000..09634a8
--- /dev/null
@@ -0,0 +1,7 @@
+/* Define if you want System V semaphore support.
+ */
+#define HAVE_SYSVSEM 0
+
+/* Define if you have union semun.
+ */
+#define HAVE_SEMUN 0
diff --git a/ext/sysvsem/config.m4 b/ext/sysvsem/config.m4
new file mode 100644 (file)
index 0000000..afdd602
--- /dev/null
@@ -0,0 +1,37 @@
+dnl $Id$
+
+AC_MSG_CHECKING(whether to enable System V semaphore support)
+AC_ARG_ENABLE(sysvsem,
+[  --enable-sysvsem        Enable System V semaphore support.],
+[
+  if test "$enableval" = "yes"; then
+    AC_MSG_RESULT(yes)
+    PHP_EXTENSION(sysvsem)
+    AC_DEFINE(HAVE_SYSVSEM, 1)
+    AC_CACHE_CHECK(for union semun,php_cv_semun,
+      AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+      ],
+      [union semun x;],
+      [
+        php_cv_semun=yes
+      ],[
+        php_cv_semun=no
+      ])
+    )
+  if test $php_cv_semun = "yes"; then
+    AC_DEFINE(HAVE_SEMUN, 1)
+  else
+    AC_DEFINE(HAVE_SEMUN, 0)
+  fi
+  else
+    AC_MSG_RESULT(no)
+    AC_DEFINE(HAVE_SYSVSEM, 0)
+  fi
+],[
+  AC_MSG_RESULT(no)
+  AC_DEFINE(HAVE_SYSVSEM, 0)
+])
+
diff --git a/ext/sysvsem/php3_sysvsem.h b/ext/sysvsem/php3_sysvsem.h
new file mode 100644 (file)
index 0000000..fcb971d
--- /dev/null
@@ -0,0 +1,74 @@
+/* 
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Tom May <tom@go2net.com>                                    |
+   +----------------------------------------------------------------------+
+ */
+
+
+/* $Id$ */
+
+#ifndef _PHP3_SYSVSEM_H
+#define _PHP3_SYSVSEM_H
+
+#if COMPILE_DL
+#undef HAVE_SYSVSEM
+#define HAVE_SYSVSEM 1
+#endif
+
+#if HAVE_SYSVSEM
+
+extern php3_module_entry sysvsem_module_entry;
+#define sysvsem_module_ptr &sysvsem_module_entry
+
+extern int php3_minit_sysvsem(INIT_FUNC_ARGS);
+extern int php3_rinit_sysvsem(INIT_FUNC_ARGS);
+extern int php3_mshutdown_sysvsem(SHUTDOWN_FUNC_ARGS);
+extern int php3_rshutdown_sysvsem(SHUTDOWN_FUNC_ARGS);
+extern void php3_info_sysvsem(void);
+extern void php3_sysvsem_get(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sysvsem_acquire(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sysvsem_release(INTERNAL_FUNCTION_PARAMETERS);
+
+typedef struct {
+       int le_sem;
+} sysvsem_module;
+
+typedef struct {
+       int id;                                         /* For error reporting. */
+       int key;                                        /* For error reporting. */
+       int semid;                                      /* Returned by semget(). */
+       int count;                                      /* Acquire count for auto-release. */
+} sysvsem_sem;
+
+extern sysvsem_module php3_sysvsem_module;
+
+#else
+
+#define sysvsem_module_ptr NULL
+
+#endif
+
+#endif /* _PHP3_SYSVSEM_H */
diff --git a/ext/sysvsem/setup.stub b/ext/sysvsem/setup.stub
new file mode 100644 (file)
index 0000000..cad1279
--- /dev/null
@@ -0,0 +1,5 @@
+# $Source$
+# $Id$
+
+define_option enable-sysvsem 'System V semaphores support? ' yesno no \
+'    Whether to use the System V semaphores (currently only solaris and linux).'
diff --git a/ext/sysvsem/sysvsem.c b/ext/sysvsem/sysvsem.c
new file mode 100644 (file)
index 0000000..2c2a9cc
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Tom May <tom@go2net.com>                                    |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+/* This has been built and tested on Solaris 2.6 and Linux 2.1.122.
+ * It may not compile or execute correctly on other systems.
+ *
+ * sas: Works for me on Linux 2.0.36 and FreeBSD 3.0-current
+ */
+
+#ifndef MSVC5
+#include "config.h"
+#endif
+
+#if HAVE_SYSVSEM
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <errno.h>
+
+#include "php.h"
+#include "php3_sysvsem.h"
+
+
+function_entry sysvsem_functions[] = {
+       {"sem_get",                             php3_sysvsem_get,                       NULL},
+       {"sem_acquire",                 php3_sysvsem_acquire,           NULL},
+       {"sem_release",                 php3_sysvsem_release,           NULL},
+       {NULL, NULL, NULL}
+};
+
+php3_module_entry sysvsem_module_entry = {
+       "System V semaphores", sysvsem_functions, php3_minit_sysvsem, NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES
+};
+
+#if COMPILE_DL
+php3_module_entry *get_module() { return &sysvsem_module_entry; }
+#endif
+
+
+THREAD_LS sysvsem_module php3_sysvsem_module;
+
+/* Semaphore functions using System V semaphores.  Each semaphore
+ * actually consists of three semaphores allocated as a unit under the
+ * same key.  Semaphore 0 (SYSVSEM_SEM) is the actual semaphore, it is
+ * initialized to max_acquire and decremented as processes acquire it.
+ * The value of semaphore 1 (SYSVSEM_USAGE) is a count of the number
+ * of processes using the semaphore.  After calling semget(), if a
+ * process finds that the usage count is 1, it will set the value of
+ * SYSVSEM_SEM to max_acquire.  This allows max_acquire to be set and
+ * track the PHP code without having a global init routine or external
+ * semaphore init code.  Except see the bug regarding a race condition
+ * php3_sysvsem_get().  Semaphore 2 (SYSVSEM_SETVAL) serializes the
+ * calls to GETVAL SYSVSEM_USAGE and SETVAL SYSVSEM_SEM.  It can be
+ * acquired only when it is zero.
+ */
+
+#define SYSVSEM_SEM            0
+#define SYSVSEM_USAGE  1
+#define SYSVSEM_SETVAL 2
+
+
+static void release_sysvsem_sem(sysvsem_sem *sem_ptr)
+{
+       struct sembuf sop[2];
+
+       /* Decrement the usage count. */
+
+       sop[0].sem_num = SYSVSEM_USAGE;
+       sop[0].sem_op  = -1;
+       sop[0].sem_flg = SEM_UNDO;
+
+       /* Release the semaphore if it has been acquired but not released. */
+
+       if (sem_ptr->count) {
+               php3_error(E_WARNING, "Releasing SysV semaphore id %d key 0x%x in request cleanup", sem_ptr->id, sem_ptr->key);
+
+               sop[1].sem_num = SYSVSEM_SEM;
+               sop[1].sem_op  = sem_ptr->count;
+               sop[1].sem_flg = SEM_UNDO;
+       }
+       if (semop(sem_ptr->semid, sop, sem_ptr->count ? 2 : 1) == -1) {
+               php3_error(E_WARNING, "semop() failed in release_sysvsem_sem for key 0x%x: %s", sem_ptr->key, strerror(errno));
+       }
+
+       efree(sem_ptr);
+}
+
+
+int php3_minit_sysvsem(INIT_FUNC_ARGS)
+{
+       php3_sysvsem_module.le_sem = register_list_destructors(release_sysvsem_sem, NULL);
+
+       return SUCCESS;
+}
+
+
+/* {{{ proto int sem_get(int key [, int max_acquire [, int perm]])
+   Return an id for the semaphore with the given key, and allow max_acquire (default 1) processes to acquire it simultaneously. */
+void php3_sysvsem_get(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *arg_key, *arg_max_acquire, *arg_perm;
+       int key, max_acquire, perm;
+    int semid;
+       struct sembuf sop[3];
+       int count;
+       sysvsem_sem *sem_ptr;
+#if HAVE_SEMUN
+       union semun un;
+#endif
+
+       max_acquire = 1;
+       perm = 0666;
+
+       switch (ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &arg_key)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_key);
+                       key = (int)arg_key->value.lval;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &arg_key, &arg_max_acquire)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_key);
+                       key = (int)arg_key->value.lval;
+                       convert_to_long(arg_max_acquire);
+                       max_acquire = (int)arg_max_acquire->value.lval;
+                       break;
+               case 3:
+                       if (getParameters(ht, 3, &arg_key, &arg_max_acquire, &arg_perm)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_key);
+                       key = (int)arg_key->value.lval;
+                       convert_to_long(arg_max_acquire);
+                       max_acquire = (int)arg_max_acquire->value.lval;
+                       convert_to_long(arg_perm);
+                       perm = (int)arg_perm->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       /* Get/create the semaphore.  Note that we rely on the semaphores
+        * being zeroed when they are created.  Despite the fact that
+        * the(?)  Linux semget() man page says they are not initialized,
+        * the kernel versions 2.0.x and 2.1.z do in fact zero them.
+        */
+
+    semid = semget(key, 3, perm|IPC_CREAT);
+       if (semid == -1) {
+               php3_error(E_WARNING, "semget() failed for key 0x%x: %s", key, strerror(errno));
+               RETURN_FALSE;
+       }
+
+       /* Find out how many processes are using this semaphore.  Note
+        * that on Linux (at least) there is a race condition here because
+        * semaphore undo on process exit is not atomic, so we could
+        * acquire SYSVSEM_SETVAL before a crashed process has decremented
+        * SYSVSEM_USAGE in which case count will be greater than it
+        * should be and we won't set max_acquire.  Fortunately this
+        * doesn't actually matter in practice.
+        */
+
+       /* Wait for sem 1 to be zero . . . */
+
+       sop[0].sem_num = SYSVSEM_SETVAL;
+       sop[0].sem_op  = 0;
+       sop[0].sem_flg = 0;
+
+       /* . . . and increment it so it becomes non-zero . . . */
+
+       sop[1].sem_num = SYSVSEM_SETVAL;
+       sop[1].sem_op  = 1;
+       sop[1].sem_flg = SEM_UNDO;
+
+       /* . . . and increment the usage count. */
+
+       sop[2].sem_num = SYSVSEM_USAGE;
+       sop[2].sem_op  = 1;
+       sop[2].sem_flg = SEM_UNDO;
+       while (semop(semid, sop, 3) == -1) {
+               if (errno != EINTR) {
+                       php3_error(E_WARNING, "semop() failed acquiring SYSVSEM_SETVAL for key 0x%x: %s", key, strerror(errno));
+                       break;
+               }
+       }
+
+       /* Get the usage count. */
+#if HAVE_SEMUN
+       count = semctl(semid, SYSVSEM_USAGE, GETVAL, un);
+#else
+       count = semctl(semid, SYSVSEM_USAGE, GETVAL, NULL);
+#endif
+       if (count == -1) {
+               php3_error(E_WARNING, "semctl(GETVAL) failed for key 0x%x: %s", key, strerror(errno));
+       }
+
+       /* If we are the only user, then take this opportunity to set the max. */
+
+       if (count == 1) {
+#if HAVE_SEMUN
+               /* This is correct for Linux which has union semun. */
+               union semun semarg;
+               semarg.val = max_acquire;
+               if (semctl(semid, SYSVSEM_SEM, SETVAL, semarg) == -1) {
+                       php3_error(E_WARNING, "semctl(SETVAL) failed for key 0x%x: %s", key, strerror(errno));
+               }
+#else
+               /* This is correct for Solaris 2.6 which does not have union semun. */
+               if (semctl(semid, SYSVSEM_SEM, SETVAL, &max_acquire) == -1) {
+                       php3_error(E_WARNING, "semctl(SETVAL) failed for key 0x%x: %s", key, strerror(errno));
+               }
+#endif
+       }
+
+       /* Set semaphore 1 back to zero. */
+
+       sop[0].sem_num = SYSVSEM_SETVAL;
+       sop[0].sem_op  = -1;
+       sop[0].sem_flg = SEM_UNDO;
+       while (semop(semid, sop, 1) == -1) {
+               if (errno != EINTR) {
+                       php3_error(E_WARNING, "semop() failed releasing SYSVSEM_SETVAL for key 0x%x: %s", key, strerror(errno));
+                       break;
+               }
+       }
+
+       sem_ptr = (sysvsem_sem *) emalloc(sizeof(sysvsem_sem));
+       sem_ptr->key   = key;
+       sem_ptr->semid = semid;
+       sem_ptr->count = 0;
+
+       return_value->value.lval = php3_list_insert(sem_ptr, php3_sysvsem_module.le_sem);
+       return_value->type = IS_LONG;
+
+       sem_ptr->id = (int)return_value->value.lval;
+}
+/* }}} */
+
+static void _php3_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire)
+{
+       pval *arg_id;
+       int id, type;
+       sysvsem_sem *sem_ptr;
+    struct sembuf sop;
+
+       switch(ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &arg_id)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_id);
+                       id = (int)arg_id->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       sem_ptr = (sysvsem_sem *) php3_list_find(id, &type);
+       if (type!=php3_sysvsem_module.le_sem) {
+               php3_error(E_WARNING, "%d is not a SysV semaphore index", id);
+               RETURN_FALSE;
+       }
+
+       if (!acquire && sem_ptr->count == 0) {
+               php3_error(E_WARNING, "SysV semaphore index %d (key 0x%x) is not currently acquired", id, sem_ptr->key);
+               RETURN_FALSE;
+       }
+
+    sop.sem_num = SYSVSEM_SEM;
+    sop.sem_op  = acquire ? -1 : 1;
+    sop.sem_flg = SEM_UNDO;
+
+    while (semop(sem_ptr->semid, &sop, 1) == -1) {
+               if (errno != EINTR) {
+                       php3_error(E_WARNING, "semop(%s) failed for key 0x%x: %s",
+                                          acquire ? "acquire" : "release",  sem_ptr->key, strerror(errno));
+                       RETURN_FALSE;
+               }
+       }
+
+       sem_ptr->count -= acquire ? -1 : 1;
+       RETURN_TRUE;
+}
+
+
+/* {{{ proto int sem_acquire(int id)
+   Acquires the semaphore with the given id, blocking if necessary. */
+void php3_sysvsem_acquire(INTERNAL_FUNCTION_PARAMETERS)
+{
+       _php3_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+}
+/* }}} */
+
+/* {{{ proto int sem_release(int id)
+   Releases the semaphore with the given id. */
+void php3_sysvsem_release(INTERNAL_FUNCTION_PARAMETERS)
+{
+       _php3_sysvsem_semop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+}
+/* }}} */
+
+#endif /* HAVE_SYSVSEM */
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/sysvshm/Makefile.am b/ext/sysvshm/Makefile.am
new file mode 100644 (file)
index 0000000..9c759a0
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_sysvshm.a
+libphpext_sysvshm_a_SOURCES=sysvshm.c
+
diff --git a/ext/sysvshm/Makefile.in b/ext/sysvshm/Makefile.in
new file mode 100644 (file)
index 0000000..27a168c
--- /dev/null
@@ -0,0 +1,270 @@
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id$
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DISTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+APACHE_INCLUDE = @APACHE_INCLUDE@
+APACHE_TARGET = @APACHE_TARGET@
+APXS = @APXS@
+APXS_LDFLAGS = @APXS_LDFLAGS@
+BINNAME = @BINNAME@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CFLAGS_SHLIB = @CFLAGS_SHLIB@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+EXTINFO_DEPS = @EXTINFO_DEPS@
+EXTRA_LIBS = @EXTRA_LIBS@
+EXT_LIBS = @EXT_LIBS@
+EXT_SUBDIRS = @EXT_SUBDIRS@
+FHTTPD_LIB = @FHTTPD_LIB@
+FHTTPD_TARGET = @FHTTPD_TARGET@
+HSREGEX = @HSREGEX@
+INSTALL_IT = @INSTALL_IT@
+LDFLAGS_SHLIB = @LDFLAGS_SHLIB@
+LDFLAGS_SHLIB_EXPORT = @LDFLAGS_SHLIB_EXPORT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+PERL_PATH = @PERL_PATH@
+PHP_BUILD_DATE = @PHP_BUILD_DATE@
+PHP_DEBUG = @PHP_DEBUG@
+PHP_LIBS = @PHP_LIBS@
+PHP_VERSION = @PHP_VERSION@
+PROG_SENDMAIL = @PROG_SENDMAIL@
+RANLIB = @RANLIB@
+RDYNAMIC_LFLAGS = @RDYNAMIC_LFLAGS@
+REGEX_LIB = @REGEX_LIB@
+STRONGHOLD = @STRONGHOLD@
+VERSION = @VERSION@
+WARNING_LEVEL = @WARNING_LEVEL@
+YACC = @YACC@
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_sysvshm.a
+libphpext_sysvshm_a_SOURCES=sysvshm.c
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libphpext_sysvshm_a_LIBADD = 
+libphpext_sysvshm_a_OBJECTS =  sysvshm.o
+AR = ar
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(libphpext_sysvshm_a_SOURCES)
+OBJECTS = $(libphpext_sysvshm_a_OBJECTS)
+
+all: Makefile $(LIBRARIES)
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: @MAINT@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps ext/sysvshm/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+       $(COMPILE) -c $<
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libphpext_sysvshm.a: $(libphpext_sysvshm_a_OBJECTS) $(libphpext_sysvshm_a_DEPENDENCIES)
+       -rm -f libphpext_sysvshm.a
+       $(AR) cru libphpext_sysvshm.a $(libphpext_sysvshm_a_OBJECTS) $(libphpext_sysvshm_a_LIBADD)
+       $(RANLIB) libphpext_sysvshm.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = ext/sysvshm
+
+distdir: $(DISTFILES)
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
+       done
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
+install-strip:
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f Makefile $(DISTCLEANFILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-generic
+
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
+               mostlyclean
+
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-generic clean
+       -rm -f config.status
+
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-generic distclean
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-exec install-data install uninstall all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ext/sysvshm/config.h.stub b/ext/sysvshm/config.h.stub
new file mode 100644 (file)
index 0000000..9b5f5e3
--- /dev/null
@@ -0,0 +1,3 @@
+/* Define if you want System V shared memory support.
+ */
+#define HAVE_SYSVSHM 0
diff --git a/ext/sysvshm/config.m4 b/ext/sysvshm/config.m4
new file mode 100644 (file)
index 0000000..287841f
--- /dev/null
@@ -0,0 +1,17 @@
+dnl $Id$
+
+AC_MSG_CHECKING(whether to enable System V shared memory support)
+AC_ARG_ENABLE(sysvshm,
+[  --enable-sysvshm        Enable the System V shared memory support],[
+  if test "$enableval" = "yes"; then
+    AC_DEFINE(HAVE_SYSVSHM, 1)
+    AC_MSG_RESULT(yes)
+    PHP_EXTENSION(sysvshm)
+  else
+    AC_DEFINE(HAVE_SYSVSHM, 0)
+    AC_MSG_RESULT(no)
+  fi
+],[
+  AC_DEFINE(HAVE_SYSVSHM, 0)
+  AC_MSG_RESULT(no)
+]) 
diff --git a/ext/sysvshm/php3_sysvshm.h b/ext/sysvshm/php3_sysvshm.h
new file mode 100644 (file)
index 0000000..c47e561
--- /dev/null
@@ -0,0 +1,101 @@
+/* 
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Christian Cartus <chc@idgruppe.de>                          |
+   +----------------------------------------------------------------------+
+ */
+
+
+/* $Id$ */
+
+#ifndef _PHP3_SYSVSHM_H
+#define _PHP3_SYSVSHM_H
+
+#if COMPILE_DL
+#undef HAVE_SYSVSHM
+#define HAVE_SYSVSHM 1
+#endif
+
+
+#if HAVE_SYSVSHM
+
+extern php3_module_entry sysvshm_module_entry;
+#define sysvshm_module_ptr &sysvshm_module_entry
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+typedef struct {
+       int le_shm;
+       long init_mem;
+} sysvshm_module;
+
+
+typedef struct {
+       long key;
+       long length;
+       long next;
+       char mem;
+} sysvshm_chunk;
+
+
+typedef struct {
+       char magic[8];
+       long start;
+       long end;
+       long free;
+       long total;
+} sysvshm_chunk_head;
+
+
+typedef struct {
+       key_t key;                                      /* Key set by user */
+       long id;                                        /* Returned by shmget. */
+       sysvshm_chunk_head *ptr;                        /* memoryaddress of shared memory */ 
+} sysvshm_shm;
+
+
+
+extern int php3_minit_sysvshm(INIT_FUNC_ARGS);
+extern void php3_sysvshm_attach(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sysvshm_detach(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sysvshm_remove(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sysvshm_put_var(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sysvshm_get_var(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_sysvshm_remove_var(INTERNAL_FUNCTION_PARAMETERS);
+extern int php3int_put_shmdata(sysvshm_chunk_head *ptr,long key,char *data, long len);
+extern long php3int_check_shmdata(sysvshm_chunk_head *ptr, long key);
+extern int php3int_remove_shmdata(sysvshm_chunk_head *ptr, long shm_varpos);
+
+extern sysvshm_module php3_sysvshm_module;
+
+#else
+
+#define sysvshm_module_ptr NULL
+
+#endif
+
+#endif /* _PHP3_SYSVSHM_H */
diff --git a/ext/sysvshm/setup.stub b/ext/sysvshm/setup.stub
new file mode 100644 (file)
index 0000000..4a9e894
--- /dev/null
@@ -0,0 +1,5 @@
+# $Source$
+# $Id$
+
+define_option enable-sysvshm 'System V shared memory support? ' yesno no \
+'    Whether to use the System V shared memory (currently only Solaris and Linux).'
diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c
new file mode 100644 (file)
index 0000000..6854728
--- /dev/null
@@ -0,0 +1,485 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Christian Cartus <chc@idgruppe.de>                          |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+
+/* This has been built and tested on Solaris 2.6.
+ * It may not compile or execute correctly on other systems.
+ */
+
+#ifndef MSVC5
+#include "config.h"
+#endif
+
+
+#if HAVE_SYSVSHM
+
+#include <errno.h>
+
+#include "php.h"
+#include "php3_var.h"
+#include "php3_sysvshm.h"
+
+
+function_entry sysvshm_functions[] = {
+       {"shm_attach",                  php3_sysvshm_attach,            NULL},
+       {"shm_detach",                  php3_sysvshm_detach,            NULL},
+       {"shm_remove",                  php3_sysvshm_remove,            NULL},
+       {"shm_put_var",                 php3_sysvshm_put_var,           NULL},
+       {"shm_get_var",                 php3_sysvshm_get_var,           NULL},
+       {"shm_remove_var",              php3_sysvshm_remove_var,        NULL},
+       {NULL, NULL, NULL}
+};
+
+php3_module_entry sysvshm_module_entry = {
+       "System V Shared-Memory", sysvshm_functions, php3_minit_sysvshm, NULL, NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES
+};
+
+
+#if COMPILE_DL
+php3_module_entry *get_module() { return &sysvshm_module_entry; }
+#endif
+
+
+THREAD_LS sysvshm_module php3_sysvshm_module;
+
+
+
+static void php3i_release_sysvshm(sysvshm_shm *shm_ptr) {
+
+       shmdt((void*)shm_ptr->ptr);
+}
+
+
+
+int php3_minit_sysvshm(INIT_FUNC_ARGS)
+{    
+       php3_sysvshm_module.le_shm = register_list_destructors(php3i_release_sysvshm, NULL);
+       if (cfg_get_long("sysvshm.init_mem",
+                      &php3_sysvshm_module.init_mem)==FAILURE) {
+               php3_sysvshm_module.init_mem=10000;
+       }       
+       return SUCCESS;
+}
+
+
+/* {{{ proto int shm_attach(int key, int size, int flag)
+   Return an id for the shared memory with the given key. */
+void php3_sysvshm_attach(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *arg_key,*arg_size,*arg_flag;
+       long shm_size,shm_flag;
+       sysvshm_shm *shm_list_ptr;
+       char *shm_ptr;
+       sysvshm_chunk_head *chunk_ptr;
+       key_t shm_key;
+       long shm_id,list_id;
+
+       shm_flag = 0666;
+       shm_size = php3_sysvshm_module.init_mem;
+       
+       switch (ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &arg_key)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_key);
+                       shm_key = arg_key->value.lval;
+                       break;
+               case 2:
+                       if (getParameters(ht, 2, &arg_key, &arg_size)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_key);
+                       shm_key = arg_key->value.lval;
+                       convert_to_long(arg_size);
+                       shm_size=arg_size->value.lval;
+                       break;
+               case 3:
+                       if (getParameters(ht, 3, &arg_key, &arg_size, &arg_flag)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_key);
+                       shm_key = arg_key->value.lval;
+                       convert_to_long(arg_size);
+                       shm_size=arg_size->value.lval;
+                       convert_to_long(arg_flag);
+                       shm_flag = arg_flag->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+
+       if((shm_list_ptr = (sysvshm_shm *) emalloc(sizeof(sysvshm_shm)))==NULL) {
+               php3_error(E_WARNING, "shm_attach() failed for key 0x%x: cannot allocate internal listelement", shm_key);
+               RETURN_FALSE;
+       }
+
+       /* get the id from a specified key or create new shared memory */
+       if((shm_id=shmget(shm_key,0,0))<0) {
+               if(shm_size<sizeof(sysvshm_chunk_head)) {
+                       php3_error(E_WARNING, "shm_attach() failed for key 0x%x: memorysize too small", shm_key);
+                       RETURN_FALSE;
+               }
+               if((shm_id=shmget(shm_key,shm_size,shm_flag|IPC_CREAT|IPC_EXCL))<0) {
+                       php3_error(E_WARNING, "shmget() failed for key 0x%x: %s", shm_key, strerror(errno));
+                       RETURN_FALSE;
+               }
+       }
+
+       if((shm_ptr = shmat(shm_id,NULL,0))==NULL) {
+               php3_error(E_WARNING, "shmget() failed for key 0x%x: %s", shm_key, strerror(errno));
+               RETURN_FALSE;
+       }
+
+       /* check if shm is already initialized */
+       chunk_ptr= (sysvshm_chunk_head*) shm_ptr;
+       if(strcmp((char*)&(chunk_ptr->magic),"PHP3SM")!=0) {
+               strcpy((char*)&(chunk_ptr->magic),"PHP3SM");    
+               chunk_ptr->start=sizeof(sysvshm_chunk_head);
+               chunk_ptr->end=chunk_ptr->start;
+               chunk_ptr->total=shm_size;
+               chunk_ptr->free=shm_size-chunk_ptr->end;
+       }
+
+
+       shm_list_ptr->key   = shm_key;
+       shm_list_ptr->id = shm_id;
+       shm_list_ptr->ptr = chunk_ptr;
+       list_id = php3_list_insert(shm_list_ptr, php3_sysvshm_module.le_shm);
+       RETURN_LONG(list_id);
+}
+/* }}} */
+
+
+
+/* {{{ proto int shm_detach(int id)
+   releases the shared memory attachment with the given id. */
+void php3_sysvshm_detach(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *arg_id;
+       long id;
+       sysvshm_shm *shm_list_ptr;
+       int type;
+
+
+       switch (ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &arg_id)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_id);
+                       id = arg_id->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       shm_list_ptr = (sysvshm_shm *) php3_list_find(id, &type);
+       if (type!=php3_sysvshm_module.le_shm) {
+               php3_error(E_WARNING, "%d is not a SysV shared memory index", id);
+               RETURN_FALSE;
+       }
+
+       if(shmdt((void*)shm_list_ptr->ptr)<0) {
+               php3_error(E_WARNING, "shm_detach() failed for id 0x%x: %s", id, strerror(errno));
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+
+
+
+
+/* {{{ proto int shm_remove(int key)
+   removes the shared memory with the given key. */
+void php3_sysvshm_remove(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *arg_key;
+       long id;
+       key_t key;
+
+
+       switch (ARG_COUNT(ht)) {
+               case 1:
+                       if (getParameters(ht, 1, &arg_key)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_key);
+                       key = arg_key->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+
+       if((id=shmget(key,0,0))<0) {
+               php3_error(E_WARNING, "%d is not a existing SysV shared memory key", key);
+               RETURN_FALSE;
+       }
+       if(shmctl(id,IPC_RMID,NULL)<0) {
+               php3_error(E_WARNING, "shm_remove() failed for key 0x%x: %s", key, strerror(errno));
+               RETURN_FALSE;
+       } 
+       RETURN_TRUE;
+}
+/* }}} */
+
+
+
+/* {{{ proto int shm_put(int id, int key, object *variable)
+   insert a variable into shared memory. */
+void php3_sysvshm_put_var(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *arg_id, *arg_key, *arg_var;
+       long key, id;
+       sysvshm_shm *shm_list_ptr;
+       int type;
+       pval shm_var;
+       int ret;        
+
+       switch (ARG_COUNT(ht)) {
+               case 3:
+                       if (getParameters(ht, 3, &arg_id, &arg_key,&arg_var)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_id);
+                       id = arg_id->value.lval;
+                       convert_to_long(arg_key);
+                       key = arg_key->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       shm_list_ptr = (sysvshm_shm *) php3_list_find(id, &type);
+       if (type!=php3_sysvshm_module.le_shm) {
+               php3_error(E_WARNING, "%d is not a SysV shared memory index", id);
+               RETURN_FALSE;
+       }
+
+       /* setup string-variable and serialize */
+       shm_var.type=IS_STRING;
+       shm_var.value.str.len=0;
+       shm_var.value.str.val=emalloc(1);
+       shm_var.value.str.val[0]=0;
+       php3api_var_serialize(&shm_var,arg_var);
+       /* insert serialized variable into shared memory */
+       ret=php3int_put_shmdata(shm_list_ptr->ptr,key,shm_var.value.str.val,shm_var.value.str.len);
+
+       /* free string */
+       efree(shm_var.value.str.val);
+       
+       if(ret==-1) {
+               php3_error(E_WARNING, "not enough shared memory left");
+               RETURN_FALSE;
+       }
+       RETURN_TRUE;
+}
+/* }}} */
+
+
+
+
+/* {{{ proto string/float/int/array shm_get_var(int id, int key)
+   returns a variable into shared memory. */
+void php3_sysvshm_get_var(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *arg_id, *arg_key;
+       long key, id;
+       sysvshm_shm *shm_list_ptr;
+       int type;
+       char *shm_data; 
+       long shm_varpos;
+       sysvshm_chunk *shm_var;
+       
+       switch (ARG_COUNT(ht)) {
+               case 2:
+                       if (getParameters(ht, 2, &arg_id, &arg_key)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_id);
+                       id = arg_id->value.lval;
+                       convert_to_long(arg_key);
+                       key = arg_key->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       shm_list_ptr = (sysvshm_shm *) php3_list_find(id, &type);
+       if (type!=php3_sysvshm_module.le_shm) {
+               php3_error(E_WARNING, "%d is not a SysV shared memory index", id);
+               RETURN_FALSE;
+       }
+
+       /* setup string-variable and serialize */
+       /* get serialized variable from shared memory */
+       shm_varpos=php3int_check_shmdata((shm_list_ptr->ptr),key);
+
+       if(shm_varpos<0) {
+               php3_error(E_WARNING, "variable key %d doesn't exist", key);
+               RETURN_FALSE;
+       }
+       shm_var=(sysvshm_chunk*)((char*)shm_list_ptr->ptr+shm_varpos);
+       shm_data=&shm_var->mem;
+       
+       if(php3api_var_unserialize(return_value, &shm_data, shm_data+shm_var->length)!=1) {
+               php3_error(E_WARNING, "variable data in shared memory is corruped");
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+/* {{{ proto int shm_remove_var(int id, int key)
+   removes variable from shared memory. */
+void php3_sysvshm_remove_var(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *arg_id, *arg_key;
+       long key, id;
+       sysvshm_shm *shm_list_ptr;
+       int type;
+       long shm_varpos;
+       
+       switch (ARG_COUNT(ht)) {
+               case 2:
+                       if (getParameters(ht, 2, &arg_id, &arg_key)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_long(arg_id);
+                       id = arg_id->value.lval;
+                       convert_to_long(arg_key);
+                       key = arg_key->value.lval;
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       break;
+       }
+
+       shm_list_ptr = (sysvshm_shm *) php3_list_find(id, &type);
+       if (type!=php3_sysvshm_module.le_shm) {
+               php3_error(E_WARNING, "%d is not a SysV shared memory index", id);
+               RETURN_FALSE;
+       }
+
+       shm_varpos=php3int_check_shmdata((shm_list_ptr->ptr),key);
+
+       if(shm_varpos<0) {
+               php3_error(E_WARNING, "variable key %d doesn't exist", key);
+               RETURN_FALSE;
+       }
+       php3int_remove_shmdata((shm_list_ptr->ptr),shm_varpos); 
+       RETURN_TRUE;
+}
+/* }}} */
+
+
+
+
+
+
+
+/* inserts an ascii-string into shared memory */
+int php3int_put_shmdata(sysvshm_chunk_head *ptr,long key,char *data, long len) {
+       sysvshm_chunk* shm_var;
+       long total_size;
+       long shm_varpos;        
+
+       total_size=((long)(len+sizeof(sysvshm_chunk)-1)/4)*4+4;    /* 4-byte alligment */
+       
+       if(ptr->free<total_size) {
+               return -1;   /* not enough memeory */
+       }
+
+       if((shm_varpos=php3int_check_shmdata(ptr,key))>0) {
+               php3int_remove_shmdata(ptr, shm_varpos);        
+       }
+       shm_var=(sysvshm_chunk*)((char *)ptr+ptr->end); 
+       shm_var->key=key;
+       shm_var->length=len;
+       shm_var->next=total_size;   
+       memcpy(&(shm_var->mem),data,len);       
+       ptr->end+=total_size;
+       ptr->free-=total_size;
+       return 0;
+}
+
+
+long php3int_check_shmdata(sysvshm_chunk_head *ptr, long key) {
+       long pos;
+       sysvshm_chunk *shm_var;
+
+       pos=ptr->start;
+                       
+       for(;;) {
+               if(pos>=ptr->end) {
+                       return -1;
+               }
+               shm_var=(sysvshm_chunk*)((char*)ptr+pos);
+               if(shm_var->key==key) {
+                       return pos;
+               }       
+               pos+=shm_var->next;
+       }
+       return -1;
+}
+
+
+int php3int_remove_shmdata(sysvshm_chunk_head *ptr, long shm_varpos) {
+       sysvshm_chunk *chunk_ptr, *next_chunk_ptr;
+       long memcpy_len;
+       
+       chunk_ptr=(sysvshm_chunk*)((char*)ptr+shm_varpos);
+       next_chunk_ptr=(sysvshm_chunk*)((char*)ptr+shm_varpos+chunk_ptr->next);
+       
+       memcpy_len=ptr->end-shm_varpos-chunk_ptr->next;
+       ptr->free+=chunk_ptr->next;
+       ptr->end-=chunk_ptr->next;
+       if(memcpy_len>0)
+               memcpy(chunk_ptr,next_chunk_ptr,memcpy_len);
+       return 0;
+}
+
+
+
+#endif /* HAVE_SYSVSHM */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/xml/Makefile.am b/ext/xml/Makefile.am
new file mode 100644 (file)
index 0000000..c4f9f52
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_xml.a
+libphpext_xml_a_SOURCES=xml.c
+
diff --git a/ext/xml/Makefile.in b/ext/xml/Makefile.in
new file mode 100644 (file)
index 0000000..8ba8f5f
--- /dev/null
@@ -0,0 +1,270 @@
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id$
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DISTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+APACHE_INCLUDE = @APACHE_INCLUDE@
+APACHE_TARGET = @APACHE_TARGET@
+APXS = @APXS@
+APXS_LDFLAGS = @APXS_LDFLAGS@
+BINNAME = @BINNAME@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CFLAGS_SHLIB = @CFLAGS_SHLIB@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+EXTINFO_DEPS = @EXTINFO_DEPS@
+EXTRA_LIBS = @EXTRA_LIBS@
+EXT_LIBS = @EXT_LIBS@
+EXT_SUBDIRS = @EXT_SUBDIRS@
+FHTTPD_LIB = @FHTTPD_LIB@
+FHTTPD_TARGET = @FHTTPD_TARGET@
+HSREGEX = @HSREGEX@
+INSTALL_IT = @INSTALL_IT@
+LDFLAGS_SHLIB = @LDFLAGS_SHLIB@
+LDFLAGS_SHLIB_EXPORT = @LDFLAGS_SHLIB_EXPORT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+PERL_PATH = @PERL_PATH@
+PHP_BUILD_DATE = @PHP_BUILD_DATE@
+PHP_DEBUG = @PHP_DEBUG@
+PHP_LIBS = @PHP_LIBS@
+PHP_VERSION = @PHP_VERSION@
+PROG_SENDMAIL = @PROG_SENDMAIL@
+RANLIB = @RANLIB@
+RDYNAMIC_LFLAGS = @RDYNAMIC_LFLAGS@
+REGEX_LIB = @REGEX_LIB@
+STRONGHOLD = @STRONGHOLD@
+VERSION = @VERSION@
+WARNING_LEVEL = @WARNING_LEVEL@
+YACC = @YACC@
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_xml.a
+libphpext_xml_a_SOURCES=xml.c
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libphpext_xml_a_LIBADD = 
+libphpext_xml_a_OBJECTS =  xml.o
+AR = ar
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(libphpext_xml_a_SOURCES)
+OBJECTS = $(libphpext_xml_a_OBJECTS)
+
+all: Makefile $(LIBRARIES)
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: @MAINT@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps ext/xml/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+       $(COMPILE) -c $<
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libphpext_xml.a: $(libphpext_xml_a_OBJECTS) $(libphpext_xml_a_DEPENDENCIES)
+       -rm -f libphpext_xml.a
+       $(AR) cru libphpext_xml.a $(libphpext_xml_a_OBJECTS) $(libphpext_xml_a_LIBADD)
+       $(RANLIB) libphpext_xml.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = ext/xml
+
+distdir: $(DISTFILES)
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
+       done
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
+install-strip:
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f Makefile $(DISTCLEANFILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-generic
+
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
+               mostlyclean
+
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-generic clean
+       -rm -f config.status
+
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-generic distclean
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-exec install-data install uninstall all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ext/xml/config.h.stub b/ext/xml/config.h.stub
new file mode 100644 (file)
index 0000000..a4abe9b
--- /dev/null
@@ -0,0 +1,4 @@
+/* define if you want to use the xml extension */
+
+/* Define if you have the expat (XML Parser Toolkit) library */
+#define HAVE_LIBEXPAT 0
diff --git a/ext/xml/config.m4 b/ext/xml/config.m4
new file mode 100644 (file)
index 0000000..c4b8711
--- /dev/null
@@ -0,0 +1,24 @@
+dnl $Id$
+
+AC_MSG_CHECKING(for XML support)
+AC_ARG_WITH(xml,
+[  --with-xml              Include XML support],[
+  if test "$withval" != "no"; then
+    if test "$withval" = "yes"; then
+      XML_LIBS="-lexpat"
+      XML_INCLUDE=""
+    else
+      XML_LIBS="-L$withval/lib -lexpat"
+      XML_INCLUDE="-I$withval/include"
+    fi
+    AC_DEFINE(HAVE_LIBEXPAT, 1)
+    AC_MSG_RESULT(yes)
+    PHP_EXTENSION(xml)
+    EXTRA_LIBS="$EXTRA_LIBS $XML_LIBS"
+    INCLUDES="$INCLUDES $XML_INCLUDE"
+  else
+    AC_MSG_RESULT(no)
+  fi
+],[
+  AC_MSG_RESULT(no)
+]) 
diff --git a/ext/xml/php3_xml.h b/ext/xml/php3_xml.h
new file mode 100644 (file)
index 0000000..7daba59
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Stig Sæther Bakken <ssb@guardian.no>                        |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id */
+
+#if HAVE_LIBEXPAT
+# ifndef _PHP_XML_H
+#  define _PHP_XML_H
+# endif
+
+#include <xml/xmltok.h>
+#include <xml/xmlparse.h>
+
+#ifdef XML_UNICODE
+# error "UTF-16 Unicode support not implemented!"
+#endif
+
+typedef struct {
+       int le_xml_parser;
+       XML_Char *default_encoding;
+} xml_module;
+
+typedef struct {
+       int index;
+       int case_folding;
+       XML_Parser parser;
+       XML_Char *target_encoding;
+       char *startElementHandler;
+       char *endElementHandler;
+       char *characterDataHandler;
+       char *processingInstructionHandler;
+       char *defaultHandler;
+       char *unparsedEntityDeclHandler;
+       char *notationDeclHandler;
+       char *externalEntityRefHandler;
+       char *unknownEncodingHandler;
+       XML_Char *baseURI;
+} xml_parser;
+
+
+typedef struct {
+       XML_Char *name;
+       char (*decoding_function)(unsigned short);
+       unsigned short (*encoding_function)(char);
+} xml_encoding;
+
+
+extern php3_module_entry xml_module_entry;
+# define xml_module_ptr &xml_module_entry
+
+enum php3_xml_option {
+    PHP3_XML_OPTION_CASE_FOLDING,
+    PHP3_XML_OPTION_TARGET_ENCODING
+};
+
+# define RETURN_OUT_OF_MEMORY \
+       php3_error(E_WARNING, "Out of memory");\
+       RETURN_FALSE
+
+PHP_FUNCTION(xml_parser_create);
+PHP_FUNCTION(xml_set_element_handler);
+PHP_FUNCTION(xml_set_character_data_handler);
+PHP_FUNCTION(xml_set_processing_instruction_handler);
+PHP_FUNCTION(xml_set_default_handler);
+PHP_FUNCTION(xml_set_unparsed_entity_decl_handler);
+PHP_FUNCTION(xml_set_notation_decl_handler);
+PHP_FUNCTION(xml_set_external_entity_ref_handler);
+PHP_FUNCTION(xml_parse);
+PHP_FUNCTION(xml_get_error_code);
+PHP_FUNCTION(xml_error_string);
+PHP_FUNCTION(xml_get_current_line_number);
+PHP_FUNCTION(xml_get_current_column_number);
+PHP_FUNCTION(xml_get_current_byte_index);
+PHP_FUNCTION(xml_parser_free);
+PHP_FUNCTION(xml_parser_set_option);
+PHP_FUNCTION(xml_parser_get_option);
+PHP_FUNCTION(utf8_encode);
+PHP_FUNCTION(utf8_decode);
+
+#else /* !HAVE_LIBEXPAT */
+
+# define xml_module_ptr NULL
+
+#endif /* HAVE_LIBEXPAT */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/xml/xml.c b/ext/xml/xml.c
new file mode 100644 (file)
index 0000000..eed6a3f
--- /dev/null
@@ -0,0 +1,1307 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Authors: Stig Sæther Bakken <ssb@guardian.no>                        |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+#define IS_EXT_MODULE
+#if COMPILE_DL
+# if PHP_31
+#  include "../phpdl.h"
+# else
+#  include "dl/phpdl.h"
+# endif
+#endif
+#include "php.h"
+#include "php3_xml.h"
+#include "zend_variables.h"
+
+#if defined(THREAD_SAFE) && !PHP_31
+#undef THREAD_SAFE
+#endif
+
+#if HAVE_LIBEXPAT
+
+# if !(WIN32|WINNT)
+#  include "build-defs.h"
+# endif
+# include "snprintf.h"
+# include "ext/standard/head.h"
+# include "php3_string.h"
+
+/* Short-term TODO list:
+ * - Implement XML_ExternalEntityParserCreate()
+ */
+
+/* Long-term TODO list:
+ * - Fix the expat library so you can install your own memory manager
+ *   functions
+ */
+
+/* Known bugs:
+ * - Weird things happen with <![CDATA[]]> sections.
+ */
+
+/* {{{ thread safety stuff */
+
+# ifdef THREAD_SAFE
+#  define XML_GLOBAL(a) xml_globals->a
+#  define XML_TLS_VARS xml_global_struct *xml_globals = TlsGetValue(XMLTls); 
+
+void *xml_mutex;
+DWORD XMLTls;
+static int numthreads=0;
+
+typedef struct xml_global_struct {
+       xml_module php3_xml_module;
+} xml_global_struct;
+
+# else /* !defined(THREAD_SAFE) */
+#  define XML_GLOBAL(a) a
+#  define XML_TLS_VARS
+
+xml_module php3_xml_module;
+
+# endif /* defined(THREAD_SAFE) */
+
+/* }}} */
+/* {{{ dynamically loadable module stuff */
+
+# if COMPILE_DL
+DLEXPORT php3_module_entry *get_module() { return &xml_module_entry; };
+# endif /* COMPILE_DL */
+
+/* }}} */
+/* {{{ function prototypes */
+
+int php3_minit_xml(INIT_FUNC_ARGS);
+int php3_rinit_xml(INIT_FUNC_ARGS);
+int php3_mshutdown_xml(SHUTDOWN_FUNC_ARGS);
+int php3_rshutdown_xml(SHUTDOWN_FUNC_ARGS);
+void php3_info_xml(void);
+
+static xml_parser *xml_get_parser(int, const char *, HashTable *);
+static void xml_destroy_parser(xml_parser *);
+static void xml_set_handler(char **, pval *);
+inline static unsigned short xml_encode_iso_8859_1(unsigned char);
+inline static char xml_decode_iso_8859_1(unsigned short);
+inline static unsigned short xml_encode_us_ascii(char);
+inline static char xml_decode_us_ascii(unsigned short);
+static XML_Char *xml_utf8_encode(const char *, int, int *, const XML_Char *);
+static char *xml_utf8_decode(const XML_Char *, int, int *, const XML_Char *);
+static pval *xml_call_handler(xml_parser *, char *, int, pval **);
+static pval *php3i_xmlcharpval(const XML_Char *, int, const XML_Char *);
+static int php3i_xmlcharlen(const XML_Char *);
+
+void php3i_xml_startElementHandler(void *, const char *, const char **);
+void php3i_xml_endElementHandler(void *, const char *);
+void php3i_xml_characterDataHandler(void *, const XML_Char *, int);
+void php3i_xml_processingInstructionHandler(void *, const XML_Char *, const XML_Char *);
+void php3i_xml_defaultHandler(void *, const XML_Char *, int);
+void php3i_xml_unparsedEntityDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
+void php3i_xml_notationDeclHandler(void *, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
+int  php3i_xml_externalEntityRefHandler(XML_Parser, const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
+
+/* }}} */
+/* {{{ extension definition structures */
+
+function_entry xml_functions[] = {
+    PHP_FE(xml_parser_create, NULL)
+    PHP_FE(xml_set_element_handler, NULL)
+       PHP_FE(xml_set_character_data_handler, NULL)
+       PHP_FE(xml_set_processing_instruction_handler, NULL)
+       PHP_FE(xml_set_default_handler, NULL)
+       PHP_FE(xml_set_unparsed_entity_decl_handler, NULL)
+       PHP_FE(xml_set_notation_decl_handler, NULL)
+       PHP_FE(xml_set_external_entity_ref_handler, NULL)
+    PHP_FE(xml_parse, NULL)
+    PHP_FE(xml_get_error_code, NULL)
+    PHP_FE(xml_error_string, NULL)
+    PHP_FE(xml_get_current_line_number, NULL)
+    PHP_FE(xml_get_current_column_number, NULL)
+    PHP_FE(xml_get_current_byte_index, NULL)
+    PHP_FE(xml_parser_free, NULL)
+       PHP_FE(xml_parser_set_option, NULL)
+       PHP_FE(xml_parser_get_option, NULL)
+       PHP_FE(utf8_encode, NULL)
+       PHP_FE(utf8_decode, NULL)
+    {NULL, NULL, NULL}
+};
+
+php3_module_entry xml_module_entry = {
+    "XML",                /* extension name */
+    xml_functions,        /* extension function list */
+    php3_minit_xml,       /* extension-wide startup function */
+    php3_mshutdown_xml,   /* extension-wide shutdown function */
+    php3_rinit_xml,       /* per-request startup function */
+    php3_rshutdown_xml,   /* per-request shutdown function */
+    php3_info_xml,        /* information function */
+    STANDARD_MODULE_PROPERTIES
+};
+
+/* All the encoding functions are set to NULL right now, since all
+ * the encoding is currently done internally by expat/xmltok.
+ */
+xml_encoding xml_encodings[] = {
+       { "ISO-8859-1", xml_decode_iso_8859_1, xml_encode_iso_8859_1 },
+       { "US-ASCII",   xml_decode_us_ascii,   xml_encode_us_ascii   },
+       { "UTF-8",      NULL,                  NULL                  },
+    { NULL,         NULL,                  NULL                  }
+};
+
+/* }}} */
+/* {{{ startup, shutdown and info functions */
+
+    /* {{{ php3_minit_xml */
+
+int php3_minit_xml(INIT_FUNC_ARGS)
+{
+#if defined(THREAD_SAFE)
+       xml_global_struct *xml_globals;
+       PHP3_MUTEX_ALLOC(xml_mutex);
+       PHP3_MUTEX_LOCK(xml_mutex);
+       numthreads++;
+       if (numthreads==1){
+               if (!PHP3_TLS_PROC_STARTUP(XMLTls)){
+                       PHP3_MUTEX_UNLOCK(xml_mutex);
+                       PHP3_MUTEX_FREE(xml_mutex);
+                       return FAILURE;
+               }
+       }
+       PHP3_MUTEX_UNLOCK(xml_mutex);
+       if(!PHP3_TLS_THREAD_INIT(XMLTls,xml_globals,xml_global_struct)){
+               PHP3_MUTEX_FREE(xml_mutex);
+               return FAILURE;
+       }
+#endif
+
+       XML_GLOBAL(php3_xml_module).le_xml_parser =
+               register_list_destructors(xml_destroy_parser, NULL);
+
+       XML_GLOBAL(php3_xml_module).default_encoding = "ISO-8859-1";
+
+       REGISTER_LONG_CONSTANT("XML_ERROR_NONE", XML_ERROR_NONE, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_NO_MEMORY", XML_ERROR_NO_MEMORY, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_SYNTAX", XML_ERROR_SYNTAX, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_NO_ELEMENTS", XML_ERROR_NO_ELEMENTS, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_INVALID_TOKEN", XML_ERROR_INVALID_TOKEN, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_UNCLOSED_TOKEN", XML_ERROR_UNCLOSED_TOKEN, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_PARTIAL_CHAR", XML_ERROR_PARTIAL_CHAR, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_TAG_MISMATCH", XML_ERROR_TAG_MISMATCH, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_DUPLICATE_ATTRIBUTE", XML_ERROR_DUPLICATE_ATTRIBUTE, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_JUNK_AFTER_DOC_ELEMENT", XML_ERROR_JUNK_AFTER_DOC_ELEMENT, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_PARAM_ENTITY_REF", XML_ERROR_PARAM_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_UNDEFINED_ENTITY", XML_ERROR_UNDEFINED_ENTITY, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_RECURSIVE_ENTITY_REF", XML_ERROR_RECURSIVE_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_ASYNC_ENTITY", XML_ERROR_ASYNC_ENTITY, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_BAD_CHAR_REF", XML_ERROR_BAD_CHAR_REF, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_BINARY_ENTITY_REF", XML_ERROR_BINARY_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF", XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_MISPLACED_XML_PI", XML_ERROR_MISPLACED_XML_PI, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_UNKNOWN_ENCODING", XML_ERROR_UNKNOWN_ENCODING, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_INCORRECT_ENCODING", XML_ERROR_INCORRECT_ENCODING, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_UNCLOSED_CDATA_SECTION", XML_ERROR_UNCLOSED_CDATA_SECTION, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_ERROR_EXTERNAL_ENTITY_HANDLING", XML_ERROR_EXTERNAL_ENTITY_HANDLING, CONST_CS|CONST_PERSISTENT);
+
+       REGISTER_LONG_CONSTANT("XML_OPTION_CASE_FOLDING", PHP3_XML_OPTION_CASE_FOLDING, CONST_CS|CONST_PERSISTENT);
+       REGISTER_LONG_CONSTANT("XML_OPTION_TARGET_ENCODING", PHP3_XML_OPTION_TARGET_ENCODING, CONST_CS|CONST_PERSISTENT);
+
+       return SUCCESS;
+}
+
+/* }}} */
+    /* {{{ php3_rinit_xml */
+
+int php3_rinit_xml(INIT_FUNC_ARGS)
+{
+    return SUCCESS;
+}
+
+/* }}} */
+    /* {{{ php3_mshutdown_xml() */
+
+int php3_mshutdown_xml(SHUTDOWN_FUNC_ARGS)
+{
+       XML_TLS_VARS;
+#ifdef THREAD_SAFE
+       PHP3_TLS_THREAD_FREE(xml_globals);
+       PHP3_MUTEX_LOCK(xml_mutex);
+       numthreads--;
+       if (numthreads<1) {
+               PHP3_TLS_PROC_SHUTDOWN(XMLTls);
+               PHP3_MUTEX_UNLOCK(xml_mutex);
+               PHP3_MUTEX_FREE(xml_mutex);
+               return SUCCESS;
+       }
+       PHP3_MUTEX_UNLOCK(xml_mutex);
+#endif
+       return SUCCESS;
+}
+
+/* }}} */
+    /* {{{ php3_rshutdown_xml() */
+
+int php3_rshutdown_xml(SHUTDOWN_FUNC_ARGS)
+{
+    return SUCCESS;
+}
+
+/* }}} */
+    /* {{{ php3_info_xml() */
+
+void php3_info_xml()
+{
+               PUTS("XML support active");
+}
+
+/* }}} */
+
+/* }}} */
+/* {{{ extension-internal functions */
+
+    /* {{{ xml_get_parser() */
+
+static xml_parser *
+xml_get_parser(int parser_ind, const char *func, HashTable *list)
+{
+       int type;
+       xml_parser *parser;
+       XML_TLS_VARS;
+
+       parser = (xml_parser *)php3_list_find(parser_ind, &type);
+       if (!parser || type != XML_GLOBAL(php3_xml_module).le_xml_parser) {
+               php3_error(E_WARNING, "%s: invalid XML parser %d", func, parser_ind);
+               return (xml_parser *)NULL;
+       }
+       return parser;
+}
+
+/* }}} */
+    /* {{{ xml_destroy_parser() */
+
+static void
+xml_destroy_parser(xml_parser *parser)
+{
+       XML_TLS_VARS;
+  
+       if (parser->parser) {
+               XML_ParserFree(parser->parser);
+       }
+       if (parser->startElementHandler) {
+               efree(parser->startElementHandler);
+       }
+       if (parser->endElementHandler) {
+               efree(parser->endElementHandler);
+       }
+       if (parser->characterDataHandler) {
+               efree(parser->characterDataHandler);
+       }
+       if (parser->processingInstructionHandler) {
+               efree(parser->processingInstructionHandler);
+       }
+       if (parser->defaultHandler) {
+               efree(parser->defaultHandler);
+       }
+       if (parser->unparsedEntityDeclHandler) {
+               efree(parser->unparsedEntityDeclHandler);
+       }
+       if (parser->notationDeclHandler) {
+               efree(parser->notationDeclHandler);
+       }
+       if (parser->externalEntityRefHandler) {
+               efree(parser->externalEntityRefHandler);
+       }
+       if (parser->unknownEncodingHandler) {
+               efree(parser->unknownEncodingHandler);
+       }
+       if (parser->baseURI) {
+               efree(parser->baseURI);
+       }
+
+       efree(parser);
+}
+
+/* }}} */
+    /* {{{ xml_set_handler() */
+
+static void
+xml_set_handler(char **nameBufp, pval *data)
+{
+       if (data->value.str.len > 0) {
+               if (*nameBufp != NULL) {
+                       efree(*nameBufp);
+               }
+               *nameBufp = php3i_pval_strdup(data);
+       } else {
+               if (*nameBufp != NULL) {
+                       efree(*nameBufp);
+               }
+               *nameBufp = NULL;
+       }
+}
+
+/* }}} */
+    /* {{{ xml_call_handler() */
+
+static pval *
+xml_call_handler(xml_parser *parser, char *funcName, int argc, pval **argv)
+{
+       if (parser && funcName) {
+               pval *retval, *func;
+               int i;
+               HashTable *function_table;
+
+               func = php3i_string_pval(funcName);
+               retval = emalloc(sizeof(pval));
+               /* We cannot call internal variables from a function module as
+                  it breaks any chance of compiling it as a module on windows.
+                  Instead, we create a callback function. */
+               function_table=php3i_get_function_table();
+               if (call_user_function(function_table, NULL, func, retval, argc, argv) == FAILURE) {
+                       php3tls_pval_destructor(retval);
+                       efree(retval);
+                       return NULL;
+               }
+               php3tls_pval_destructor(func);
+               efree(func);
+               for (i = 0; i < argc; i++) {
+                       php3tls_pval_destructor(argv[i]);
+                       efree(argv[i]);
+               }
+               return retval;
+       }
+       return NULL;
+}
+
+/* }}} */
+    /* {{{ xml_encode_iso_8859_1() */
+
+inline static unsigned short
+xml_encode_iso_8859_1(unsigned char c)
+{
+       php3_printf("c=%d ", c);
+       return (unsigned short)c;
+}
+
+/* }}} */
+    /* {{{ xml_decode_iso_8859_1() */
+
+inline static char
+xml_decode_iso_8859_1(unsigned short c)
+{
+       return (char)(c > 0xff ? '?' : c);
+}
+
+/* }}} */
+    /* {{{ xml_encode_us_ascii() */
+
+inline static unsigned short
+xml_encode_us_ascii(char c)
+{
+       return (unsigned short)c;
+}
+
+/* }}} */
+    /* {{{ xml_decode_us_ascii() */
+
+inline static char
+xml_decode_us_ascii(unsigned short c)
+{
+       return (char)(c > 0x7f ? '?' : c);
+}
+
+/* }}} */
+    /* {{{ xml_get_encoding() */
+
+static xml_encoding *
+xml_get_encoding(const XML_Char *name)
+{
+       xml_encoding *enc = &xml_encodings[0];
+
+       while (enc && enc->name) {
+               if (strcasecmp(name, enc->name) == 0) {
+                       return enc;
+               }
+               enc++;
+       }
+       return NULL;
+}
+
+/* }}} */
+    /* {{{ xml_utf8_encode */
+static XML_Char *
+xml_utf8_encode(const char *s, int len, int *newlen, const XML_Char *encoding)
+{
+       int pos = len;
+       char *newbuf;
+       unsigned short c;
+       unsigned short (*encoder)(char) = NULL;
+       xml_encoding *enc = xml_get_encoding(encoding);
+
+       *newlen = 0;
+       if (enc) {
+               encoder = enc->encoding_function;
+       } else {
+               /* If the target encoding was unknown, fail */
+               return NULL;
+       }
+       if (encoder == NULL) {
+               /* If no encoder function was specified, return the data as-is.
+                */
+               newbuf = emalloc(len);
+               memcpy(newbuf, s, len);
+               *newlen = len;
+               return newbuf;
+       }
+       /* This is the theoretical max (will never get beyond len * 2 as long
+        * as we are converting from single-byte characters, though) */
+       newbuf = emalloc(len * 4);
+       while (pos > 0) {
+               c = encoder ? encoder((unsigned char)(*s)) : (unsigned short)(*s);
+               if (c < 0x80) {
+                       newbuf[(*newlen)++] = c;
+               } else if (c < 0x800) {
+                       newbuf[(*newlen)++] = (0xc0 | (c >> 6));
+                       newbuf[(*newlen)++] = (0x80 | (c & 0x3f));
+               } else if (c < 0x10000) {
+                       newbuf[(*newlen)++] = (0xe0 | (c >> 12));
+                       newbuf[(*newlen)++] = (0xc0 | ((c >> 6) & 0x3f));
+                       newbuf[(*newlen)++] = (0x80 | (c & 0x3f));
+               } else if (c < 0x200000) {
+                       newbuf[(*newlen)++] = (0xf0 | (c >> 18));
+                       newbuf[(*newlen)++] = (0xe0 | ((c >> 12) & 0x3f));
+                       newbuf[(*newlen)++] = (0xc0 | ((c >> 6) & 0x3f));
+                       newbuf[(*newlen)++] = (0x80 | (c & 0x3f));
+               }
+               pos--;
+               s++;
+    }
+       if (*newlen < len * 4) {
+               newbuf = erealloc(newbuf, *newlen);
+       }
+       return newbuf;
+}
+/* }}} */
+    /* {{{ xml_utf8_decode */
+static char *
+xml_utf8_decode(const XML_Char *s, int len, int *newlen, const XML_Char *encoding)
+{
+       int pos = len;
+       char *newbuf = emalloc(len);
+       unsigned short c;
+       char (*decoder)(unsigned short) = NULL;
+       xml_encoding *enc = xml_get_encoding(encoding);
+
+       *newlen = 0;
+       if (enc) {
+               decoder = enc->decoding_function;
+       }
+       if (decoder == NULL) {
+               /* If the target encoding was unknown, or no decoder function
+                * was specified, return the UTF-8-encoded data as-is.
+                */
+               memcpy(newbuf, s, len);
+               *newlen = len;
+               return newbuf;
+       }
+       while (pos > 0) {
+               c = (unsigned char)(*s);
+               if (c >= 0xf0) { /* four bytes encoded, 21 bits */
+                       c = ((s[0]&7)<<18) | ((s[1]&63)<<12) | ((s[2]&63)<<6) | (s[3]&63);
+                       s += 4;
+                       pos -= 4;
+               } else if (c >= 0xe0) { /* three bytes encoded, 16 bits */
+                       c = ((s[0]&63)<<12) | ((s[1]&63)<<6) | (s[2]&63);
+                       s += 3;
+                       pos -= 3;
+               } else if (c >= 0xc0) { /* two bytes encoded, 11 bits */
+                       c = ((s[0]&63)<<6) | (s[1]&63);
+                       s += 2;
+                       pos -= 2;
+               } else {
+                       s++;
+                       pos--;
+               }
+               newbuf[*newlen] = decoder ? decoder(c) : c;
+               ++*newlen;
+    }
+       if (*newlen < len) {
+               newbuf = erealloc(newbuf, *newlen);
+       }
+       return newbuf;
+}
+/* }}} */
+    /* {{{ php3i_xmlcharpval() */
+
+static pval *php3i_xmlcharpval(const XML_Char *s, int len, const XML_Char *encoding)
+{
+       pval *ret = emalloc(sizeof(pval));
+
+       if (s == NULL) {
+               var_reset(ret);
+               return ret;
+       }
+       if (len == 0) {
+               len = php3i_xmlcharlen(s);
+       }
+       ret->type = IS_STRING;
+       ret->value.str.val = xml_utf8_decode(s, len, &ret->value.str.len, encoding);
+       return ret;
+}
+
+/* }}} */
+    /* {{{ php3i_xmlcharlen() */
+
+static int php3i_xmlcharlen(const XML_Char *s)
+{
+       int len = 0;
+
+       while (*s) {
+               len++;
+               s++;
+       }
+       return len;
+}
+
+/* }}} */
+    /* {{{ php3i_xml_startElementHandler() */
+
+void php3i_xml_startElementHandler(void *userData, const char *name,
+                                                                  const char **attributes)
+{
+       xml_parser *parser = (xml_parser *)userData;
+       XML_TLS_VARS;
+
+       if (parser && parser->startElementHandler) {
+               pval *retval, *args[3];
+
+               if (parser->case_folding) {
+                       name = _php3_strtoupper(estrdup(name));
+               }
+               args[0] = php3i_long_pval(parser->index);
+               args[1] = php3i_string_pval(name);
+               args[2] = emalloc(sizeof(pval));
+               array_init(args[2]);
+               while (attributes && *attributes) {
+                       char *key = (char *)attributes[0];
+                       char *value = (char *)attributes[1];
+                       if (parser->case_folding) {
+                               key = _php3_strtoupper(estrdup(key));
+                       }
+                       add_assoc_string(args[2], key, value, 1);
+                       if (parser->case_folding) {
+                               efree(key);
+                       }
+                       attributes += 2;
+               }
+               if ((retval = xml_call_handler(parser, parser->startElementHandler, 3, args))) {
+                       php3tls_pval_destructor(retval);
+                       efree(retval);
+               }
+               if (parser->case_folding) {
+                       efree((char *)name);
+               }
+       }
+}
+
+/* }}} */
+    /* {{{ php3i_xml_endElementHandler() */
+
+void php3i_xml_endElementHandler(void *userData, const char *name)
+{
+       xml_parser *parser = (xml_parser *)userData;
+       XML_TLS_VARS;
+
+       if (parser && parser->endElementHandler) {
+               pval *retval, *args[2];
+
+               if (parser->case_folding) {
+                       name = _php3_strtoupper(estrdup(name));
+               }
+               args[0] = php3i_long_pval(parser->index);
+               args[1] = php3i_string_pval(name);
+               if ((retval = xml_call_handler(parser, parser->endElementHandler, 2, args))) {
+                       php3tls_pval_destructor(retval);
+                       efree(retval);
+               }
+               if (parser->case_folding) {
+                       efree((char *)name);
+               }
+       }
+}
+
+/* }}} */
+    /* {{{ php3i_xml_characterDataHandler() */
+
+void php3i_xml_characterDataHandler(void *userData, const XML_Char *s, int len)
+{
+       xml_parser *parser = (xml_parser *)userData;
+       XML_TLS_VARS;
+
+       if (parser && parser->characterDataHandler) {
+               pval *retval, *args[2];
+
+               args[0] = php3i_long_pval(parser->index);
+               args[1] = php3i_xmlcharpval(s, len, parser->target_encoding);
+               if ((retval = xml_call_handler(parser, parser->characterDataHandler, 2, args))) {
+                       php3tls_pval_destructor(retval);
+                       efree(retval);
+               }
+       }
+}
+
+/* }}} */
+    /* {{{ php3i_xml_processingInstructionHandler() */
+
+void php3i_xml_processingInstructionHandler(void *userData,
+                                                                                       const XML_Char *target,
+                                                                                       const XML_Char *data)
+{
+       xml_parser *parser = (xml_parser *)userData;
+       XML_TLS_VARS;
+
+       if (parser && parser->processingInstructionHandler) {
+               pval *retval, *args[3];
+
+               args[0] = php3i_long_pval(parser->index);
+               args[1] = php3i_xmlcharpval(target, 0, parser->target_encoding);
+               args[2] = php3i_xmlcharpval(data, 0, parser->target_encoding);
+               if ((retval = xml_call_handler(parser, parser->processingInstructionHandler, 3, args))) {
+                       php3tls_pval_destructor(retval);
+                       efree(retval);
+               }
+       }
+}
+
+/* }}} */
+    /* {{{ php3i_xml_defaultHandler() */
+
+void php3i_xml_defaultHandler(void *userData, const XML_Char *s, int len)
+{
+       xml_parser *parser = (xml_parser *)userData;
+       XML_TLS_VARS;
+
+       if (parser && parser->defaultHandler) {
+               pval *retval, *args[2];
+
+               args[0] = php3i_long_pval(parser->index);
+               args[1] = php3i_xmlcharpval(s, len, parser->target_encoding);
+               if ((retval = xml_call_handler(parser, parser->defaultHandler, 2, args))) {
+                       php3tls_pval_destructor(retval);
+                       efree(retval);
+               }
+       }
+}
+
+/* }}} */
+    /* {{{ php3i_xml_unparsedEntityDeclHandler() */
+
+void php3i_xml_unparsedEntityDeclHandler(void *userData,
+                                                                                const XML_Char *entityName,
+                                                                                const XML_Char *base,
+                                                                                const XML_Char *systemId,
+                                                                                const XML_Char *publicId,
+                                                                                const XML_Char *notationName)
+{
+       xml_parser *parser = (xml_parser *)userData;
+       XML_TLS_VARS;
+
+       if (parser && parser->unparsedEntityDeclHandler) {
+               pval *retval, *args[5];
+
+               args[0] = php3i_long_pval(parser->index);
+               args[1] = php3i_xmlcharpval(entityName, 0, parser->target_encoding);
+               args[2] = php3i_xmlcharpval(base, 0, parser->target_encoding);
+               args[3] = php3i_xmlcharpval(systemId, 0, parser->target_encoding);
+               args[4] = php3i_xmlcharpval(publicId, 0, parser->target_encoding);
+               args[5] = php3i_xmlcharpval(notationName, 0, parser->target_encoding);
+               if ((retval = xml_call_handler(parser, parser->unparsedEntityDeclHandler, 6, args))) {
+                       php3tls_pval_destructor(retval);
+                       efree(retval);
+               }
+       }
+}
+
+/* }}} */
+    /* {{{ php3i_xml_notationDeclHandler() */
+
+void
+php3i_xml_notationDeclHandler(void *userData,
+                                                         const XML_Char *notationName,
+                                                         const XML_Char *base,
+                                                         const XML_Char *systemId,
+                                                         const XML_Char *publicId)
+{
+       xml_parser *parser = (xml_parser *)userData;
+       XML_TLS_VARS;
+
+       if (parser && parser->notationDeclHandler) {
+               pval *retval, *args[5];
+
+               args[0] = php3i_long_pval(parser->index);
+               args[1] = php3i_xmlcharpval(notationName, 0, parser->target_encoding);
+               args[2] = php3i_xmlcharpval(base, 0, parser->target_encoding);
+               args[3] = php3i_xmlcharpval(systemId, 0, parser->target_encoding);
+               args[4] = php3i_xmlcharpval(publicId, 0, parser->target_encoding);
+               if ((retval = xml_call_handler(parser, parser->notationDeclHandler, 5, args))) {
+                       php3tls_pval_destructor(retval);
+                       efree(retval);
+               }
+       }
+}
+
+/* }}} */
+    /* {{{ php3i_xml_externalEntityRefHandler() */
+
+int
+php3i_xml_externalEntityRefHandler(XML_Parser parserPtr,
+                                                                  const XML_Char *openEntityNames,
+                                                                  const XML_Char *base,
+                                                                  const XML_Char *systemId,
+                                                                  const XML_Char *publicId)
+{
+       xml_parser *parser = XML_GetUserData(parserPtr);
+       int ret = 0; /* abort if no handler is set (should be configurable?) */
+       XML_TLS_VARS;
+
+       if (parser && parser->externalEntityRefHandler) {
+               pval *retval, *args[5];
+
+               args[0] = php3i_long_pval(parser->index);
+               args[1] = php3i_xmlcharpval(openEntityNames, 0, parser->target_encoding);
+               args[2] = php3i_xmlcharpval(base, 0, parser->target_encoding);
+               args[3] = php3i_xmlcharpval(systemId, 0, parser->target_encoding);
+               args[4] = php3i_xmlcharpval(publicId, 0, parser->target_encoding);
+               if ((retval = xml_call_handler(parser, parser->externalEntityRefHandler, 5, args))) {
+                       convert_to_long(retval);
+                       ret = retval->value.lval;
+                       efree(retval);
+               } else {
+                       ret = 0;
+               }
+       }
+       return ret;
+}
+
+/* }}} */
+
+/* }}} */
+
+/************************* EXTENSION FUNCTIONS *************************/
+
+/* {{{ int    xml_parser_create() */
+
+PHP_FUNCTION(xml_parser_create)
+{
+       xml_parser *parser;
+       int id, argc;
+       pval *encodingArg = NULL;
+       XML_Char *encoding;
+       char thisfunc[] = "xml_parser_create";
+       XML_TLS_VARS;
+
+       argc = ARG_COUNT(ht);
+
+       if (argc > 1 || getParameters(ht, argc, &encodingArg) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       if (argc == 1) {
+               convert_to_string(encodingArg);
+               /* The supported encoding types are hardcoded here because
+                * we are limited to the encodings supported by expat/xmltok.
+                */
+               if (strncasecmp(encodingArg->value.str.val, "ISO-8859-1",
+                                               encodingArg->value.str.len) == 0) {
+                       encoding = "ISO-8859-1";
+               } else if (strncasecmp(encodingArg->value.str.val, "UTF-8",
+                                               encodingArg->value.str.len) == 0) {
+                       encoding = "UTF-8";
+               } else if (strncasecmp(encodingArg->value.str.val, "US-ASCII",
+                                               encodingArg->value.str.len) == 0) {
+                       encoding = "US-ASCII";
+               } else { /* UTF-16 not supported */
+                       php3_error(E_WARNING, "%s: unsupported source encoding \"%s\"",
+                                          thisfunc, encodingArg->value.str.val);
+                       RETURN_FALSE;
+               }
+       } else {
+               encoding = XML_GLOBAL(php3_xml_module).default_encoding;
+       }
+
+       parser = ecalloc(sizeof(xml_parser), 1);
+       parser->parser = XML_ParserCreate(encoding);
+       parser->target_encoding = encoding;
+       XML_SetUserData(parser->parser, parser);
+       XML_SetElementHandler(parser->parser, php3i_xml_startElementHandler, php3i_xml_endElementHandler);
+       XML_SetCharacterDataHandler(parser->parser, php3i_xml_characterDataHandler);
+       XML_SetProcessingInstructionHandler(parser->parser, php3i_xml_processingInstructionHandler);
+       XML_SetDefaultHandler(parser->parser, php3i_xml_defaultHandler);
+       XML_SetUnparsedEntityDeclHandler(parser->parser, php3i_xml_unparsedEntityDeclHandler);
+       XML_SetNotationDeclHandler(parser->parser, php3i_xml_notationDeclHandler);
+       XML_SetExternalEntityRefHandler(parser->parser, php3i_xml_externalEntityRefHandler);
+       id = php3_list_insert(parser, XML_GLOBAL(php3_xml_module).le_xml_parser);
+       parser = xml_get_parser(id, thisfunc, list);
+       parser->index = id;
+       parser->case_folding = 1;
+
+       RETVAL_LONG(id);
+}
+
+/* }}} */
+/* {{{ int    xml_set_element_handler(int pind, string shdl, string ehdl) */
+
+PHP_FUNCTION(xml_set_element_handler)
+{
+       xml_parser *parser;
+       pval *pind, *shdl, *ehdl;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 ||
+               getParameters(ht, 3, &pind, &shdl, &ehdl) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_string(shdl);
+       convert_to_string(ehdl);
+       parser = xml_get_parser(pind->value.lval, "xml_set_element_handler", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       xml_set_handler(&parser->startElementHandler, shdl);
+       xml_set_handler(&parser->endElementHandler, ehdl);
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_set_character_data_handler(int pind, string hdl) */
+
+PHP_FUNCTION(xml_set_character_data_handler)
+{
+       xml_parser *parser;
+       pval *pind, *hdl;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &pind, &hdl) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_string(hdl);
+       parser = xml_get_parser(pind->value.lval, "xml_set_character_data_handler", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       xml_set_handler(&parser->characterDataHandler, hdl);
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_set_processing_instruction_handler(int pind, string hdl) */
+
+PHP_FUNCTION(xml_set_processing_instruction_handler)
+{
+       xml_parser *parser;
+       pval *pind, *hdl;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &pind, &hdl) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_string(hdl);
+       parser = xml_get_parser(pind->value.lval, "xml_set_processing_instruction_handler", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       xml_set_handler(&parser->processingInstructionHandler, hdl);
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_set_default_handler(int pind, string hdl) */
+
+PHP_FUNCTION(xml_set_default_handler)
+{
+       xml_parser *parser;
+       pval *pind, *hdl;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &pind, &hdl) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_string(hdl);
+       parser = xml_get_parser(pind->value.lval, "xml_set_default_handler", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       xml_set_handler(&parser->defaultHandler, hdl);
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_set_unparsed_entity_decl_handler(int pind, string hdl) */
+
+PHP_FUNCTION(xml_set_unparsed_entity_decl_handler)
+{
+       xml_parser *parser;
+       pval *pind, *hdl;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &pind, &hdl) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_string(hdl);
+       parser = xml_get_parser(pind->value.lval, "xml_set_unparsed_entity_decl_handler", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       xml_set_handler(&parser->unparsedEntityDeclHandler, hdl);
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_set_notation_decl_handler(int pind, string hdl) */
+
+PHP_FUNCTION(xml_set_notation_decl_handler)
+{
+       xml_parser *parser;
+       pval *pind, *hdl;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &pind, &hdl) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_string(hdl);
+       parser = xml_get_parser(pind->value.lval, "xml_set_notation_decl_handler", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       xml_set_handler(&parser->notationDeclHandler, hdl);
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_set_external_entity_ref_handler(int pind, string hdl) */
+
+PHP_FUNCTION(xml_set_external_entity_ref_handler)
+{
+       xml_parser *parser;
+       pval *pind, *hdl;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &pind, &hdl) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_string(hdl);
+       parser = xml_get_parser(pind->value.lval, "xml_set_external_entity_ref_handler", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       xml_set_handler(&parser->externalEntityRefHandler, hdl);
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_parse(int pind, string data[, int isFinal]) */
+
+PHP_FUNCTION(xml_parse)
+{
+       xml_parser *parser;
+       pval *pind, *data, *final;
+       int argc, isFinal, ret;
+       XML_TLS_VARS;
+
+       argc = ARG_COUNT(ht);
+       if (argc < 2 || argc > 3 || getParameters(ht, argc, &pind, &data, &final) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_string(data);
+       if (argc == 3) {
+               convert_to_long(final);
+               isFinal = final->value.lval;
+       } else {
+               isFinal = 0;
+       }
+       parser = xml_get_parser(pind->value.lval, "XML_Parse", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       fflush(stdout);
+       ret = XML_Parse(parser->parser, data->value.str.val, data->value.str.len, isFinal);
+       RETVAL_LONG(ret);
+}
+
+/* }}} */
+/* {{{ int    xml_get_error_code(int pind) */
+
+PHP_FUNCTION(xml_get_error_code)
+{
+       xml_parser *parser;
+       pval *pind;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &pind) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       parser = xml_get_parser(pind->value.lval, "xml_get_error_code", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       RETVAL_LONG((long)XML_GetErrorCode(parser->parser));
+}
+
+/* }}} */
+/* {{{ string xml_error_string(int code) */
+
+PHP_FUNCTION(xml_error_string)
+{
+       pval *code;
+       char *str;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &code) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(code);
+       str = (char *)XML_ErrorString((int)code->value.lval);
+       if (str) {
+               RETVAL_STRING(str, 1);
+       }
+}
+
+/* }}} */
+/* {{{ int    xml_get_current_line_number(int pind) */
+
+PHP_FUNCTION(xml_get_current_line_number)
+{
+       xml_parser *parser;
+       pval *pind;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &pind) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       parser = xml_get_parser(pind->value.lval, "xml_get_current_line_number", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       RETVAL_LONG(XML_GetCurrentLineNumber(parser->parser));
+}
+
+/* }}} */
+/* {{{ int    xml_get_current_column_number(int pind) */
+
+PHP_FUNCTION(xml_get_current_column_number)
+{
+       xml_parser *parser;
+       pval *pind;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &pind) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       parser = xml_get_parser(pind->value.lval, "xml_get_current_column_number", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       RETVAL_LONG(XML_GetCurrentColumnNumber(parser->parser));
+}
+
+/* }}} */
+/* {{{ int    xml_get_current_byte_index(int pind) */
+
+PHP_FUNCTION(xml_get_current_byte_index)
+{
+       xml_parser *parser;
+       pval *pind;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &pind) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       parser = xml_get_parser(pind->value.lval, "xml_get_current_byte_index", list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       RETVAL_LONG(XML_GetCurrentByteIndex(parser->parser));
+}
+
+/* }}} */
+/* {{{ int    xml_parser_free(int pind) */
+
+PHP_FUNCTION(xml_parser_free)
+{
+       pval *pind;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &pind) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       if (php3_list_delete(pind->value.lval) == FAILURE) {
+               RETURN_FALSE;
+       }
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_parser_set_option(int pind, int option, mixed value) */
+
+PHP_FUNCTION(xml_parser_set_option)
+{
+       xml_parser *parser;
+       pval *pind, *opt, *val;
+       char thisfunc[] = "xml_parser_set_option";
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 3 || getParameters(ht, 3, &pind, &opt, &val) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_long(opt);
+       parser = xml_get_parser(pind->value.lval, thisfunc, list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       switch (opt->value.lval) {
+               case PHP3_XML_OPTION_CASE_FOLDING:
+                       convert_to_long(val);
+                       parser->case_folding = val->value.lval;
+                       break;
+               case PHP3_XML_OPTION_TARGET_ENCODING: {
+                       xml_encoding *enc = xml_get_encoding(val->value.str.val);
+                       if (enc == NULL) {
+                               php3_error(E_WARNING, "%s: unsupported target encoding \"%s\"",
+                                                  thisfunc, val->value.str.val);
+                               RETURN_FALSE;
+                       }
+                       parser->target_encoding = enc->name;
+                       break;
+               }
+               default:
+                       php3_error(E_WARNING, "%s: unknown option", thisfunc);
+                       RETURN_FALSE;
+                       break;
+       }
+       RETVAL_TRUE;
+}
+
+/* }}} */
+/* {{{ int    xml_parser_get_option(int pind, int option) */
+
+PHP_FUNCTION(xml_parser_get_option)
+{
+       xml_parser *parser;
+       pval *pind, *opt;
+       char thisfunc[] = "xml_parser_get_option";
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &pind, &opt) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(pind);
+       convert_to_long(opt);
+       parser = xml_get_parser(pind->value.lval, thisfunc, list);
+       if (parser == NULL) {
+               RETURN_FALSE;
+       }
+       switch (opt->value.lval) {
+               case PHP3_XML_OPTION_CASE_FOLDING:
+                       RETURN_LONG(parser->case_folding);
+                       break;
+               case PHP3_XML_OPTION_TARGET_ENCODING:
+                       RETURN_STRING(parser->target_encoding, 1);
+                       break;
+               default:
+                       php3_error(E_WARNING, "%s: unknown option", thisfunc);
+                       RETURN_FALSE;
+                       break;
+       }
+       RETVAL_FALSE;
+}
+
+/* }}} */
+/* {{{ string utf8_encode(string data) */
+
+PHP_FUNCTION(utf8_encode)
+{
+       pval *arg;
+       XML_Char *encoded;
+       int len;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_string(arg);
+       encoded = xml_utf8_encode(arg->value.str.val, arg->value.str.len, &len, "ISO-8859-1");
+       if (encoded == NULL) {
+               RETURN_FALSE;
+       }
+       RETVAL_STRINGL(encoded, len, 0);
+}
+
+/* }}} */
+/* {{{ string utf8_decode(string data) */
+
+PHP_FUNCTION(utf8_decode)
+{
+       pval *arg;
+       XML_Char *decoded;
+       int len;
+       XML_TLS_VARS;
+
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_string(arg);
+       decoded = xml_utf8_decode(arg->value.str.val, arg->value.str.len, &len, "ISO-8859-1");
+       if (decoded == NULL) {
+               RETURN_FALSE;
+       }
+       RETVAL_STRINGL(decoded, len, 0);
+}
+
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/zlib/Makefile.am b/ext/zlib/Makefile.am
new file mode 100644 (file)
index 0000000..ef7d3ea
--- /dev/null
@@ -0,0 +1,6 @@
+# $Id$
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_zlib.a
+libphpext_zlib_a_SOURCES=zlib.c
+
diff --git a/ext/zlib/Makefile.in b/ext/zlib/Makefile.in
new file mode 100644 (file)
index 0000000..24bf631
--- /dev/null
@@ -0,0 +1,270 @@
+# Makefile.in generated automatically by automake 1.3 from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# $Id$
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DISTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ../..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+APACHE_INCLUDE = @APACHE_INCLUDE@
+APACHE_TARGET = @APACHE_TARGET@
+APXS = @APXS@
+APXS_LDFLAGS = @APXS_LDFLAGS@
+BINNAME = @BINNAME@
+CC = @CC@
+CFLAGS = @CFLAGS@
+CFLAGS_SHLIB = @CFLAGS_SHLIB@
+DEBUG_CFLAGS = @DEBUG_CFLAGS@
+EXTINFO_DEPS = @EXTINFO_DEPS@
+EXTRA_LIBS = @EXTRA_LIBS@
+EXT_LIBS = @EXT_LIBS@
+EXT_SUBDIRS = @EXT_SUBDIRS@
+FHTTPD_LIB = @FHTTPD_LIB@
+FHTTPD_TARGET = @FHTTPD_TARGET@
+HSREGEX = @HSREGEX@
+INSTALL_IT = @INSTALL_IT@
+LDFLAGS_SHLIB = @LDFLAGS_SHLIB@
+LDFLAGS_SHLIB_EXPORT = @LDFLAGS_SHLIB_EXPORT@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+PACKAGE = @PACKAGE@
+PERL_PATH = @PERL_PATH@
+PHP_BUILD_DATE = @PHP_BUILD_DATE@
+PHP_DEBUG = @PHP_DEBUG@
+PHP_LIBS = @PHP_LIBS@
+PHP_VERSION = @PHP_VERSION@
+PROG_SENDMAIL = @PROG_SENDMAIL@
+RANLIB = @RANLIB@
+RDYNAMIC_LFLAGS = @RDYNAMIC_LFLAGS@
+REGEX_LIB = @REGEX_LIB@
+STRONGHOLD = @STRONGHOLD@
+VERSION = @VERSION@
+WARNING_LEVEL = @WARNING_LEVEL@
+YACC = @YACC@
+
+INCLUDES=@INCLUDES@ -I@top_srcdir@ -I@top_srcdir@/libzend
+noinst_LIBRARIES=libphpext_zlib.a
+libphpext_zlib_a_SOURCES=zlib.c
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../../config.h
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libphpext_zlib_a_LIBADD = 
+libphpext_zlib_a_OBJECTS =  zlib.o
+AR = ar
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+SOURCES = $(libphpext_zlib_a_SOURCES)
+OBJECTS = $(libphpext_zlib_a_OBJECTS)
+
+all: Makefile $(LIBRARIES)
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: @MAINT@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps ext/zlib/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+.c.o:
+       $(COMPILE) -c $<
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+libphpext_zlib.a: $(libphpext_zlib_a_OBJECTS) $(libphpext_zlib_a_DEPENDENCIES)
+       -rm -f libphpext_zlib.a
+       $(AR) cru libphpext_zlib.a $(libphpext_zlib_a_OBJECTS) $(libphpext_zlib_a_LIBADD)
+       $(RANLIB) libphpext_zlib.a
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = ext/zlib
+
+distdir: $(DISTFILES)
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         test -f $(distdir)/$$file \
+         || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+         || cp -p $$d/$$file $(distdir)/$$file; \
+       done
+info:
+dvi:
+check: all
+       $(MAKE)
+installcheck:
+install-exec: 
+       @$(NORMAL_INSTALL)
+
+install-data: 
+       @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+       @:
+
+uninstall: 
+
+install-strip:
+       $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+       -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f Makefile $(DISTCLEANFILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+mostlyclean:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-tags mostlyclean-generic
+
+clean:  clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
+               mostlyclean
+
+distclean:  distclean-noinstLIBRARIES distclean-compile distclean-tags \
+               distclean-generic clean
+       -rm -f config.status
+
+maintainer-clean:  maintainer-clean-noinstLIBRARIES \
+               maintainer-clean-compile maintainer-clean-tags \
+               maintainer-clean-generic distclean
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir info dvi installcheck \
+install-exec install-data install uninstall all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ext/zlib/config.h.stub b/ext/zlib/config.h.stub
new file mode 100644 (file)
index 0000000..5d6dcad
--- /dev/null
@@ -0,0 +1,2 @@
+/* Define if you have the zlib library */
+#define HAVE_ZLIB 0
diff --git a/ext/zlib/config.m4 b/ext/zlib/config.m4
new file mode 100644 (file)
index 0000000..d9d3d75
--- /dev/null
@@ -0,0 +1,38 @@
+dnl $Id$
+
+AC_MSG_CHECKING(whether to include zlib support)
+AC_ARG_WITH(zlib,
+[  --with-zlib[=DIR]       Include zlib support (requires zlib >= 1.0.9).
+                          DIR is the zlib install directory,
+                          defaults to /usr.],
+[
+  case "$withval" in
+    no)
+      AC_MSG_RESULT(no) ;;
+    yes)
+      AC_MSG_RESULT(yes)
+      PHP_EXTENSION(zlib)
+      AC_CHECK_LIB(z, gzgets, [AC_DEFINE(HAVE_ZLIB) ZLIB_LIBS="-lz"],
+        [AC_MSG_ERROR(Zlib module requires zlib >= 1.0.9.)])
+      EXTRA_LIBS="$EXTRA_LIBS $ZLIB_LIBS"
+      ;;
+    *)
+      test -f $withval/include/zlib/zlib.h && ZLIB_INCLUDE="-I$withval/include/zlib"
+      test -f $withval/include/zlib.h && ZLIB_INCLUDE="-I$withval/include"
+      if test -n "$ZLIB_INCLUDE" ; then
+        AC_MSG_RESULT(yes)
+        PHP_EXTENSION(zlib)
+        old_LIBS=$LIBS
+        LIBS="$LIBS -L$withval/lib"
+        AC_CHECK_LIB(z, gzgets, [AC_DEFINE(HAVE_ZLIB) ZLIB_LIBS="-L$withval/lib -lz"],
+          [AC_MSG_ERROR(Zlib module requires zlib >= 1.0.9.)])
+        LIBS=$old_LIBS
+        EXTRA_LIBS="$EXTRA_LIBS $ZLIB_LIBS"
+        INCLUDES="$INCLUDES $ZLIB_INCLUDE"
+      else
+        AC_MSG_RESULT(no)
+      fi ;;
+  esac
+],[
+  AC_MSG_RESULT(no)
+])
diff --git a/ext/zlib/php3_zlib.h b/ext/zlib/php3_zlib.h
new file mode 100644 (file)
index 0000000..22052fb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of the GNU General Public License as published by |
+   | the Free Software Foundation; either version 2 of the License, or    |
+   | (at your option) any later version.                                  |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of the GNU General Public License    |
+   | along with this program; if not, write to the Free Software          |
+   | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            |
+   +----------------------------------------------------------------------+
+   | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
+   |          Stefan Röhrich <sr@linux.de>                                |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef _PHP3_ZLIB_H
+#define _PHP3_ZLIB_H
+
+#if COMPILE_DL
+#undef HAVE_ZLIB
+#define HAVE_ZLIB 1
+#endif
+
+#if HAVE_ZLIB
+
+extern php3_module_entry php3_zlib_module_entry;
+#define php3_zlib_module_ptr &php3_zlib_module_entry
+
+extern int php3_minit_zlib(INIT_FUNC_ARGS);
+extern int php3_mshutdown_zlib(SHUTDOWN_FUNC_ARGS);
+extern void php3_info_zlib(void);
+extern void php3_gzopen(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzclose(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzeof(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzread(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzgetc(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzgets(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzgetss(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzwrite(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzrewind(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gztell(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzseek(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzpassthru(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_readgzfile(INTERNAL_FUNCTION_PARAMETERS);
+extern void php3_gzfile(INTERNAL_FUNCTION_PARAMETERS);
+
+#else
+#define php3_zlib_module_ptr NULL
+#endif /* HAVE_ZLIB */
+
+#endif /* _PHP3_ZLIB_H */
diff --git a/ext/zlib/setup.stub b/ext/zlib/setup.stub
new file mode 100644 (file)
index 0000000..1589787
--- /dev/null
@@ -0,0 +1,7 @@
+# $Source$
+# $Id$
+
+define_option with-zlib 'zlib (>= 1.0.9) support? ' yesnodir \
+    'no /usr zlib install' \
+'    Whether to use the zlib support to read/write .gz-files.\n
+    Requires zlib version >= 1.0.9!'
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
new file mode 100644 (file)
index 0000000..e8f80c4
--- /dev/null
@@ -0,0 +1,926 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of the GNU General Public License as published by |
+   | the Free Software Foundation; either version 2 of the License, or    |
+   | (at your option) any later version.                                  |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of the GNU General Public License    |
+   | along with this program; if not, write to the Free Software          |
+   | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            |
+   +----------------------------------------------------------------------+
+   | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
+   |          Stefan Röhrich <sr@linux.de>                                |
+   +----------------------------------------------------------------------+
+ */
+/* $Id$ */
+#if !PHP_31 && defined(THREAD_SAFE)
+#undef THREAD_SAFE
+#endif
+#define IS_EXT_MODULE
+
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include "php.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#if (WIN32|WINNT)
+#include <windows.h>
+#include <winsock.h>
+#define O_RDONLY _O_RDONLY
+#if PHP_31
+#include "os/nt/param.h"
+#else
+#include "win32/param.h"
+#endif
+#else
+#include <sys/param.h>
+/* #include <sys/uio.h> */
+#endif
+#include "ext/standard/head.h"
+#include "safe_mode.h"
+#include "ext/standard/php3_standard.h"
+#include "php3_zlib.h"
+#include "fopen-wrappers.h"
+#if HAVE_PWD_H
+#if WIN32|WINNT
+#include "win32/pwd.h"
+#else
+#include <pwd.h>
+#endif
+#endif
+#include "snprintf.h"
+#if HAVE_ZLIB
+#if defined(HAVE_UNISTD_H) && (WIN32|WINNT)
+#undef HAVE_UNISTD_H
+#endif
+
+#include <zlib.h>
+
+#if COMPILE_DL
+#if PHP_31
+#include "ext/phpdl.h"
+#else
+#include "dl/phpdl.h"
+#endif
+#ifndef PUTS
+#define PUTS(a) php3_printf("%s",a)
+#endif
+#ifndef PUTC
+#define PUTC(a) PUTS(a)
+#endif
+#ifndef PHPWRITE
+#define PHPWRITE(a,n) php3_write((a),(n))
+#endif
+#endif
+
+
+
+#if defined(THREAD_SAFE)
+typedef struct zlib_global_struct{
+#endif
+       int gzgetss_state;
+       int le_zp;
+#if PHP_31
+       int magic_quotes_runtime;
+       int     safe_mode;
+       char *include_path;
+       char *doc_root;
+#endif
+#if defined(THREAD_SAFE)
+}zlib_global_struct;
+#endif
+
+#if defined(THREAD_SAFE)
+DWORD ZLIBtls;
+static int numthreads=0;
+void *zlib_mutex;
+
+#define ZLIB_GLOBAL(a) zlib_globals->a
+
+#define ZLIB_TLS_VARS zlib_global_struct *PHP3_TLS_GET(ZLIBtls,zlib_globals); 
+
+#else
+#define ZLIB_GLOBAL(a) a
+#define ZLIB_TLS_VARS
+#endif
+
+#if PHP_31
+# define ZLIB_INI(a) ZLIB_GLOBAL(a)
+#else
+# define ZLIB_INI(a) php3_ini.a
+#endif
+
+function_entry php3_zlib_functions[] = {
+       {"readgzfile",  php3_readgzfile,        NULL},
+       {"gzrewind",    php3_gzrewind,          NULL},
+       {"gzclose",             php3_gzclose,           NULL},
+       {"gzeof",               php3_gzeof,                     NULL},
+       {"gzgetc",              php3_gzgetc,            NULL},
+       {"gzgets",              php3_gzgets,            NULL},
+       {"gzgetss",             php3_gzgetss,           NULL},
+       {"gzread",              php3_gzread,            NULL},
+       {"gzopen",              php3_gzopen,            NULL},
+       {"gzpassthru",  php3_gzpassthru,        NULL},
+       {"gzseek",              php3_gzseek,            NULL},
+       {"gztell",              php3_gztell,            NULL},
+       {"gzwrite",             php3_gzwrite,           NULL},
+       {"gzputs",              php3_gzwrite,           NULL},
+       {"gzfile",              php3_gzfile,            NULL},
+       {NULL, NULL, NULL}
+};
+
+php3_module_entry php3_zlib_module_entry = {
+       "zlib", php3_zlib_functions, php3_minit_zlib, php3_mshutdown_zlib, NULL, NULL, php3_info_zlib, STANDARD_MODULE_PROPERTIES
+};
+
+#if defined(COMPILE_DL)
+DLEXPORT php3_module_entry *get_module(void) { return &php3_zlib_module_entry; }
+#endif
+
+int php3_minit_zlib(INIT_FUNC_ARGS)
+{
+#ifdef THREAD_SAFE
+       zlib_global_struct *zlib_globals;
+       PHP3_MUTEX_ALLOC(zlib_mutex);
+       PHP3_MUTEX_LOCK(zlib_mutex);
+       numthreads++;
+       if (numthreads==1){
+               if (!PHP3_TLS_PROC_STARTUP(ZLIBtls)){
+                       PHP3_MUTEX_UNLOCK(zlib_mutex);
+                       PHP3_MUTEX_FREE(zlib_mutex);
+                       return FAILURE;
+               }
+       }
+       PHP3_MUTEX_UNLOCK(zlib_mutex);
+       if(!PHP3_TLS_THREAD_INIT(ZLIBtls,zlib_globals,zlib_global_struct)){
+               PHP3_MUTEX_FREE(zlib_mutex);
+               return FAILURE;
+       }
+#endif
+       /* get our ini variables here */
+       cfg_get_long("safe_mode",&ZLIB_INI(safe_mode));
+       cfg_get_long("magic_quotes_runtime",&ZLIB_INI(magic_quotes_runtime));
+       cfg_get_string("doc_root",&ZLIB_INI(doc_root));
+       cfg_get_string("include_path",&ZLIB_INI(include_path));
+
+       ZLIB_GLOBAL(le_zp) = register_list_destructors(gzclose,NULL);
+       return SUCCESS;
+}
+
+int php3_mshutdown_zlib(SHUTDOWN_FUNC_ARGS){
+#if defined(THREAD_SAFE)
+       ZLIB_TLS_VARS;
+       PHP3_TLS_THREAD_FREE(zlib_globals);
+       PHP3_MUTEX_LOCK(zlib_mutex);
+       numthreads--;
+       if (numthreads<1){
+               PHP3_TLS_PROC_SHUTDOWN(ZLIBtls);
+               PHP3_MUTEX_UNLOCK(zlib_mutex);
+               PHP3_MUTEX_FREE(zlib_mutex);
+               return SUCCESS;
+       }
+       PHP3_MUTEX_UNLOCK(zlib_mutex);
+#endif
+       return SUCCESS;
+}
+
+void php3_info_zlib(void)
+{
+               PUTS("Zlib support active (compiled with ");
+               PUTS(ZLIB_VERSION);
+               PUTS(", linked with ");
+               PUTS((char *)zlibVersion());
+               PUTS(").");
+}
+
+static gzFile *php3_gzopen_with_path(char *filename, char *mode, char *path, char **opened_path);
+
+static gzFile php3_gzopen_wrapper(char *path, char *mode, int options)
+{
+       ZLIB_TLS_VARS;
+       if (options & USE_PATH && ZLIB_INI(include_path) != NULL) {
+               return php3_gzopen_with_path(path, mode, ZLIB_INI(include_path), NULL);
+       }
+       else {
+               if (options & ENFORCE_SAFE_MODE && ZLIB_INI(safe_mode) && (!_php3_checkuid(path,1))) {
+                       return NULL;
+               }
+               if (_php3_check_open_basedir(path)) return NULL;
+               return gzopen(path, mode);
+       }
+}
+
+/*
+ * Tries to open a .gz-file with a PATH-style list of directories.
+ * If the filename starts with "." or "/", the path is ignored.
+ */
+static gzFile *php3_gzopen_with_path(char *filename, char *mode, char *path, char **opened_path)
+{
+       char *pathbuf, *ptr, *end;
+       char trypath[MAXPATHLEN + 1];
+       struct stat sb;
+       gzFile *zp;
+       ZLIB_TLS_VARS;
+       
+       if (opened_path) {
+               *opened_path = NULL;
+       }
+       
+       /* Relative path open */
+       if (*filename == '.') {
+               if (ZLIB_INI(safe_mode) &&(!_php3_checkuid(filename,2))) {
+                       return(NULL);
+               }
+               if (_php3_check_open_basedir(filename)) return NULL;
+               zp = gzopen(filename, mode);
+               if (zp && opened_path) {
+                       *opened_path = expand_filepath(filename);
+               }
+               return zp;
+       }
+
+       /* Absolute path open - prepend document_root in safe mode */
+#if WIN32|WINNT
+       if ((*filename == '\\')||(*filename == '/')||(filename[1] == ':')) {
+#else
+       if (*filename == '/') {
+#endif
+               if (ZLIB_INI(safe_mode)) {
+                       snprintf(trypath,MAXPATHLEN,"%s%s",ZLIB_INI(doc_root),filename);
+                       if (!_php3_checkuid(trypath,2)) {
+                               return(NULL);
+                       }
+                       if (_php3_check_open_basedir(trypath)) return NULL;
+                       zp = gzopen(trypath, mode);
+                       if (zp && opened_path) {
+                               *opened_path = expand_filepath(trypath);
+                       }
+                       return zp;
+               } else {
+                       if (_php3_check_open_basedir(filename)) return NULL;
+                       return gzopen(filename, mode);
+               }
+       }
+
+       if (!path || (path && !*path)) {
+               if (ZLIB_INI(safe_mode) &&(!_php3_checkuid(filename,2))) {
+                       return(NULL);
+               }
+               if (_php3_check_open_basedir(filename)) return NULL;
+               zp = gzopen(filename, mode);
+               if (zp && opened_path) {
+                       *opened_path = strdup(filename);
+               }
+               return zp;
+       }
+
+       pathbuf = estrdup(path);
+
+       ptr = pathbuf;
+
+       while (ptr && *ptr) {
+#if WIN32|WINNT
+               end = strchr(ptr, ';');
+#else
+               end = strchr(ptr, ':');
+#endif
+               if (end != NULL) {
+                       *end = '\0';
+                       end++;
+               }
+               snprintf(trypath, MAXPATHLEN, "%s/%s", ptr, filename);
+               if (ZLIB_INI(safe_mode)) {
+                       if (stat(trypath,&sb) == 0 &&(!_php3_checkuid(trypath,2))) {
+                               efree(pathbuf);
+                               return(NULL);
+                       }
+               }
+               if ((zp = gzopen(trypath, mode)) != NULL) {
+                       if (_php3_check_open_basedir(trypath)) {
+                               gzclose(zp);
+                               efree(pathbuf);
+                               return NULL;
+                       }
+                       if (opened_path) {
+                               *opened_path = expand_filepath(trypath);
+                       }
+                       efree(pathbuf);
+                       return zp;
+               }
+               ptr = end;
+       }
+       efree(pathbuf);
+       return NULL;
+}
+
+/* {{{ proto array gzfile(string filename)
+Read und uncompress entire .gz-file into an array */
+void php3_gzfile(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *filename, *arg2;
+       gzFile zp;
+       char *slashed, buf[8192];
+       register int i=0;
+       int use_include_path = 0;
+       ZLIB_TLS_VARS;
+
+       /* check args */
+       switch (ARG_COUNT(ht)) {
+       case 1:
+               if (getParameters(ht,1,&filename) == FAILURE) {
+                       WRONG_PARAM_COUNT;
+               }
+               break;
+       case 2:
+               if (getParameters(ht,2,&filename,&arg2) == FAILURE) {
+                       WRONG_PARAM_COUNT;
+               }
+               convert_to_long(arg2);
+               use_include_path = arg2->value.lval;
+               break;
+       default:
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_string(filename);
+
+       zp = php3_gzopen_wrapper(filename->value.str.val,"r", use_include_path|ENFORCE_SAFE_MODE);
+       if (!zp) {
+               php3_error(E_WARNING,"gzFile(\"%s\") - %s",filename->value.str.val,strerror(errno));
+               RETURN_FALSE;
+       }
+
+       /* Initialize return array */
+       if (array_init(return_value) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       /* Now loop through the file and do the magic quotes thing if needed */
+       memset(buf,0,8191);
+       while((int)gzgets(zp, buf, 8191)) {
+               if (ZLIB_INI(magic_quotes_runtime)) {
+                       int len;
+                       
+                       slashed = _php3_addslashes(buf,0,&len,0); /* 0 = don't free source string */
+            add_index_stringl(return_value, i++, slashed, len, 0);
+               } else {
+                       add_index_string(return_value, i++, buf, 1);
+               }
+       }
+       gzclose(zp);
+}
+/* }}} */
+
+/* {{{ proto int gzopen(string filename, string mode [, int use_include_path])
+Open a .gz-file and return a .gz-file pointer */
+void php3_gzopen(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3;
+       gzFile *zp;
+       char *p;
+       int id;
+       int use_include_path = 0;
+       ZLIB_TLS_VARS;
+       
+       switch(ARG_COUNT(ht)) {
+       case 2:
+               if (getParameters(ht,2,&arg1,&arg2) == FAILURE) {
+                       WRONG_PARAM_COUNT;
+               }
+               break;
+       case 3:
+               if (getParameters(ht,3,&arg1,&arg2,&arg3) == FAILURE) {
+                       WRONG_PARAM_COUNT;
+               }
+               convert_to_long(arg3);
+               use_include_path = arg3->value.lval;
+               break;
+       default:
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_string(arg1);
+       convert_to_string(arg2);
+       p = estrndup(arg2->value.str.val,arg2->value.str.len);
+
+       /*
+        * We need a better way of returning error messages from
+        * php3_gzopen_wrapper().
+        */
+       zp = php3_gzopen_wrapper(arg1->value.str.val, p, use_include_path|ENFORCE_SAFE_MODE);
+       if (!zp) {
+               php3_error(E_WARNING,"gzopen(\"%s\",\"%s\") - %s",
+                                       arg1->value.str.val, p, strerror(errno));
+               efree(p);
+               RETURN_FALSE;
+       }
+       ZLIB_GLOBAL(gzgetss_state)=0;
+       id = php3_list_insert(zp,ZLIB_GLOBAL(le_zp));
+       efree(p);
+       RETURN_LONG(id);
+}      
+/* }}} */
+
+/* {{{ proto int gzclose(int zp)
+Close an open .gz-file pointer */
+void php3_gzclose(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       gzFile *zp;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       id=arg1->value.lval;
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+       php3_list_delete(id);
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int gzeof(int zp)
+Test for end-of-file on a .gz-file pointer */
+void php3_gzeof(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       gzFile *zp;
+       int id, type;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       id = arg1->value.lval;
+       zp = php3_list_find(id,&type);
+       if ((!zp || (type!=ZLIB_GLOBAL(le_zp)))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               /* we're at the eof if the file doesn't exist */
+               RETURN_TRUE;
+       }
+       if ((gzeof(zp))) {
+               RETURN_TRUE;
+       } else {
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+/* {{{ proto string gzgets(int zp, int length)
+Get a line from .gz-file pointer */
+void php3_gzgets(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       gzFile *zp;
+       int id, len, type;
+       char *buf;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       convert_to_long(arg2);
+       id = arg1->value.lval;
+       len = arg2->value.lval;
+
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp)))  {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+       buf = emalloc(sizeof(char) * (len + 1));
+       /* needed because recv doesnt put a null at the end*/
+       memset(buf,0,len+1);
+       if (!((int)gzgets(zp, buf, len))) {
+               efree(buf);
+               RETVAL_FALSE;
+       } else {
+               if (ZLIB_INI(magic_quotes_runtime)) {
+                       return_value->value.str.val = _php3_addslashes(buf,0,&return_value->value.str.len,1);
+               } else {
+                       return_value->value.str.val = buf;
+                       return_value->value.str.len = strlen(return_value->value.str.val);
+               }
+               return_value->type = IS_STRING;
+       }
+       return;
+}
+/* }}} */
+
+/* {{{ proto string gzgetc(int zp)
+Get a character from .gz-file pointer */
+void php3_gzgetc(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       gzFile *zp;
+       int id, type, c;
+       char *buf;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       id = arg1->value.lval;
+
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+       buf = emalloc(sizeof(char) * 2);
+       if ((c=gzgetc(zp)) == (-1)) {
+               efree(buf);
+               RETVAL_FALSE;
+       } else {
+               buf[0]=(char)c;
+               buf[1]='\0';
+               return_value->value.str.val = buf; 
+               return_value->value.str.len = 1; 
+               return_value->type = IS_STRING;
+       }
+       return;
+}
+/* }}} */
+
+/* Strip any HTML tags while reading */
+/* {{{ proto string gzgetss(int zp, int length)
+Get a line from file pointer and strip HTML tags */
+void php3_gzgetss(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *fd, *bytes;
+       gzFile *zp;
+       int id, len, br, type;
+       char *buf, *p, *rbuf, *rp, c, lc;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &fd, &bytes) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_long(fd);
+       convert_to_long(bytes);
+
+       id = fd->value.lval;
+       len = bytes->value.lval;
+
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING, "Unable to find gz-file identifier %d", id);
+               RETURN_FALSE;
+       }
+
+       buf = emalloc(sizeof(char) * (len + 1));
+       /*needed because recv doesnt set null char at end*/
+       memset(buf,0,len+1);
+       if (!((int)gzgets(zp, buf, len))) {
+               efree(buf);
+               RETURN_FALSE;
+       }
+
+       rbuf = estrdup(buf);
+       c = *buf;
+       lc = '\0';
+       p = buf;
+       rp = rbuf;
+       br = 0;
+
+       while (c) {
+               switch (c) {
+                       case '<':
+                               if (ZLIB_GLOBAL(gzgetss_state) == 0) {
+                                       lc = '<';
+                                       ZLIB_GLOBAL(gzgetss_state) = 1;
+                               }
+                               break;
+
+                       case '(':
+                               if (ZLIB_GLOBAL(gzgetss_state) == 2) {
+                                       if (lc != '\"') {
+                                               lc = '(';
+                                               br++;
+                                       }
+                               } else if (ZLIB_GLOBAL(gzgetss_state) == 0) {
+                                       *(rp++) = c;
+                               }
+                               break;  
+
+                       case ')':
+                               if (ZLIB_GLOBAL(gzgetss_state) == 2) {
+                                       if (lc != '\"') {
+                                               lc = ')';
+                                               br--;
+                                       }
+                               } else if (ZLIB_GLOBAL(gzgetss_state) == 0) {
+                                       *(rp++) = c;
+                               }
+                               break;  
+
+                       case '>':
+                               if (ZLIB_GLOBAL(gzgetss_state) == 1) {
+                                       lc = '>';
+                                       ZLIB_GLOBAL(gzgetss_state) = 0;
+                               } else if (ZLIB_GLOBAL(gzgetss_state) == 2) {
+                                       if (!br && lc != '\"') {
+                                               ZLIB_GLOBAL(gzgetss_state) = 0;
+                                       }
+                               }
+                               break;
+
+                       case '\"':
+                               if (ZLIB_GLOBAL(gzgetss_state) == 2) {
+                                       if (lc == '\"') {
+                                               lc = '\0';
+                                       } else if (lc != '\\') {
+                                               lc = '\"';
+                                       }
+                               } else if (ZLIB_GLOBAL(gzgetss_state) == 0) {
+                                       *(rp++) = c;
+                               }
+                               break;
+
+                       case '?':
+                               if (ZLIB_GLOBAL(gzgetss_state)==1) {
+                                       br=0;
+                                       ZLIB_GLOBAL(gzgetss_state)=2;
+                                       break;
+                               }
+                               /* fall-through */
+
+                       default:
+                               if (ZLIB_GLOBAL(gzgetss_state) == 0) {
+                                       *(rp++) = c;
+                               }       
+               }
+               c = *(++p);
+       }       
+       *rp = '\0';
+       efree(buf);
+       RETVAL_STRING(rbuf,1);
+       efree(rbuf);
+}
+/* }}} */
+
+/* {{{ proto int gzwrite(int zp, string str [, int length])
+Binary-safe .gz-file write */
+void php3_gzwrite(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2, *arg3=NULL;
+       gzFile *zp;
+       int ret,id,type;
+       int num_bytes;
+       ZLIB_TLS_VARS;
+
+       switch (ARG_COUNT(ht)) {
+               case 2:
+                       if (getParameters(ht, 2, &arg1, &arg2)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_string(arg2);
+                       num_bytes = arg2->value.str.len;
+                       break;
+               case 3:
+                       if (getParameters(ht, 3, &arg1, &arg2, &arg3)==FAILURE) {
+                               RETURN_FALSE;
+                       }
+                       convert_to_string(arg2);
+                       convert_to_long(arg3);
+                       num_bytes = MIN(arg3->value.lval, arg2->value.str.len);
+                       break;
+               default:
+                       WRONG_PARAM_COUNT;
+                       /* NOTREACHED */
+                       break;
+       }                               
+       convert_to_long(arg1);
+       id = arg1->value.lval;  
+
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+
+       /* strip slashes only if the length wasn't specified explicitly */
+       if (!arg3 && ZLIB_INI(magic_quotes_runtime)) {
+               _php3_stripslashes(arg2->value.str.val,&num_bytes);
+       }
+
+       ret = gzwrite(zp, arg2->value.str.val,num_bytes);
+       RETURN_LONG(ret);
+}      
+/* }}} */
+
+/* {{{ proto int gzrewind(int zp)
+Rewind the position of a .gz-file pointer */
+void php3_gzrewind(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id,type;
+       gzFile *zp;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       id = arg1->value.lval;  
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+       gzrewind(zp);
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int gztell(int zp)
+Get .gz-file pointer's read/write position */
+void php3_gztell(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       int id, type;
+       long pos;
+       gzFile *zp;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       id = arg1->value.lval;  
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+       pos = gztell(zp);
+       RETURN_LONG(pos);
+}
+/* }}} */
+
+/* {{{ proto int gzseek(int zp, int offset)
+Seek on a file pointer */
+void php3_gzseek(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       int ret,id,type;
+       long pos;
+       gzFile *zp;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       convert_to_long(arg2);
+       pos = arg2->value.lval;
+       id = arg1->value.lval;
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+       ret = gzseek(zp,pos,SEEK_SET);
+       RETURN_LONG(ret);
+}
+/* }}} */
+
+/*
+ * Read a file and write the ouput to stdout
+ */
+/* {{{ proto int readgzfile(string filename [, int use_include_path])
+Output a .gz-file */
+void php3_readgzfile(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1, *arg2;
+       char buf[8192];
+       gzFile *zp;
+       int b, size;
+       int use_include_path = 0;
+
+       
+       /* check args */
+       switch (ARG_COUNT(ht)) {
+       case 1:
+               if (getParameters(ht,1,&arg1) == FAILURE) {
+                       WRONG_PARAM_COUNT;
+               }
+               break;
+       case 2:
+               if (getParameters(ht,2,&arg1,&arg2) == FAILURE) {
+                       WRONG_PARAM_COUNT;
+               }
+               convert_to_long(arg2);
+               use_include_path = arg2->value.lval;
+               break;
+       default:
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_string(arg1);        
+
+       /*
+        * We need a better way of returning error messages from
+        * php3_gzopen_wrapper().
+        */
+       zp = php3_gzopen_wrapper(arg1->value.str.val,"r", use_include_path|ENFORCE_SAFE_MODE);
+       if (!zp){
+               php3_error(E_WARNING,"ReadGzFile(\"%s\") - %s",arg1->value.str.val,strerror(errno));
+               RETURN_FALSE;
+       }
+       size= 0;
+       while((b = gzread(zp, buf, sizeof(buf))) > 0) {
+               PHPWRITE(buf,b);
+               size += b ;
+       }
+       gzclose(zp);
+       RETURN_LONG(size);
+}
+/* }}} */
+
+/*
+ * Read to EOF on a file descriptor and write the output to stdout.
+ */
+/* {{{ proto int gzpassthru(int zp)
+Output all remaining data from a .gz-file pointer */
+void php3_gzpassthru(INTERNAL_FUNCTION_PARAMETERS) {
+       pval *arg1;
+       gzFile *zp;
+       char buf[8192];
+       int id, size, b, type;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &arg1) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       id = arg1->value.lval;
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+       size = 0;
+       while((b = gzread(zp, buf, sizeof(buf))) > 0) {
+               PHPWRITE(buf,b);
+               size += b ;
+       }
+/*  gzclose(zp); */
+       php3_list_delete(id);
+       RETURN_LONG(size);
+}
+/* }}} */
+
+/* {{{ proto int gzread(int zp, int length)
+Binary-safe file read */
+void php3_gzread(INTERNAL_FUNCTION_PARAMETERS)
+{
+       pval *arg1, *arg2;
+       gzFile *zp;
+       int id, len, type;
+       ZLIB_TLS_VARS;
+       
+       if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+       convert_to_long(arg1);
+       convert_to_long(arg2);
+       id = arg1->value.lval;
+       len = arg2->value.lval;
+
+       zp = php3_list_find(id,&type);
+       if (!zp || (type!=ZLIB_GLOBAL(le_zp))) {
+               php3_error(E_WARNING,"Unable to find gz-file identifier %d",id);
+               RETURN_FALSE;
+       }
+       return_value->value.str.val = emalloc(sizeof(char) * (len + 1));
+       /* needed because recv doesnt put a null at the end*/
+       
+       return_value->value.str.len = gzread(zp, return_value->value.str.val, len);
+       return_value->value.str.val[return_value->value.str.len] = 0;
+
+       if (ZLIB_INI(magic_quotes_runtime)) {
+               return_value->value.str.val = _php3_addslashes(return_value->value.str.val,return_value->value.str.len,&return_value->value.str.len,1);
+       }
+       return_value->type = IS_STRING;
+}
+/* }}} */
+
+#endif /* HAVE_ZLIB */
+/*
+ * Local variables:
+ * tab-width: 4
+ * End:
+ */
diff --git a/fhttpd.c b/fhttpd.c
new file mode 100644 (file)
index 0000000..46d7551
--- /dev/null
+++ b/fhttpd.c
@@ -0,0 +1,199 @@
+/*
+   +----------------------------------------------------------------------+
+   | PHP HTML Embedded Scripting Language Version 3.0                     |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997,1998 PHP Development Team (See Credits file)      |
+   +----------------------------------------------------------------------+
+   | This program is free software; you can redistribute it and/or modify |
+   | it under the terms of one of the following licenses:                 |
+   |                                                                      |
+   |  A) the GNU General Public License as published by the Free Software |
+   |     Foundation; either version 2 of the License, or (at your option) |
+   |     any later version.                                               |
+   |                                                                      |
+   |  B) the PHP License as published by the PHP Development Team and     |
+   |     included in the distribution in the file: LICENSE                |
+   |                                                                      |
+   | This program is distributed in the hope that it will be useful,      |
+   | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
+   | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        |
+   | GNU General Public License for more details.                         |
+   |                                                                      |
+   | You should have received a copy of both licenses referred to here.   |
+   | If you did not, or have any questions about PHP licensing, please    |
+   | contact core@php.net.                                                |
+   +----------------------------------------------------------------------+
+   | Author: Alex Belits <abelits@phobos.illtel.denver.co.us>             |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+#ifdef THREAD_SAFE
+#include "tls.h"
+#endif
+#include "php.h"
+
+#include <stdlib.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#if FHTTPD
+#include <servproc.h>
+#include <signal.h>
+
+struct http_server *server = NULL;
+struct request *req = NULL;
+struct httpresponse *response = NULL;
+int headermade = 0;
+int global_alarmflag = 0;
+int idle_timeout = IDLE_TIMEOUT;
+int exit_status = 0;
+char **currentheader = NULL;
+char *headerfirstline = NULL;
+int headerlines = 0;
+static int headerlinesallocated = 0;
+
+void alarmhandler(SIGACTARGS)
+{
+       global_alarmflag = 1;
+}
+
+void setalarm(int t)
+{
+       struct sigaction tmpsigaction;
+       global_alarmflag = 0;
+       if (t){
+               bzero((char *) &tmpsigaction, sizeof(struct sigaction));
+               tmpsigaction.sa_handler = alarmhandler;
+               sigaddset(&tmpsigaction.sa_mask, SIGALRM);
+               tmpsigaction.sa_flags = 0;
+               sigaction(SIGALRM, &tmpsigaction, NULL);
+               alarm(t);
+       }
+}
+
+int checkinput(int h)
+{
+       fd_set readfd;
+       FD_ZERO(&readfd);
+       FD_SET(h, &readfd);
+       return select(h + 1, &readfd, NULL, NULL, NULL) > 0;
+}
+
+
+PHPAPI void php3_fhttpd_free_header(void)
+{
+       int i;
+
+       if (headerfirstline) {
+               free(headerfirstline);
+               headerfirstline = NULL;
+       }
+       if (currentheader) {
+               for (i = 0; i < headerlines; i++) {
+                       free(currentheader[i]);
+               }
+               free(currentheader);
+               currentheader = NULL;
+       }
+       headerlines = 0;
+       headerlinesallocated = 0;
+       headermade = 0;
+}
+
+
+PHPAPI void php3_fhttpd_puts_header(char *s)
+{
+       char *p0, *p1, *p2, *p3, **p;
+       int l;
+
+       if (!s || !*s || *s == '\r' || *s == '\n')
+               return;
+       l = strlen(s);
+       p2 = strchr(s, '\r');
+       p3 = strchr(s, '\n');
+       p0 = strchr(s, ':');
+       p1 = strchr(s, ' ');
+       if (p0 && (!p1 || p1 > p0)) {
+               if (!headerlinesallocated) {
+                       currentheader = (char **) malloc(10 * sizeof(char *));
+                       if (currentheader)
+                               headerlinesallocated = 10;
+               } else {
+                       if (headerlinesallocated <= headerlines) {
+                               p = (char **) realloc(currentheader, (headerlinesallocated + 10) * sizeof(char *));
+                               if (p) {
+                                       currentheader = p;
+                                       headerlinesallocated += 10;
+                               }
+                       }
+               }
+
+               if (headerlinesallocated > headerlines) {
+                       currentheader[headerlines] = malloc(l + 3);
+                       if (currentheader[headerlines]) {
+                               strcpy(currentheader[headerlines], s);
+                               if (!p3) {
+                                       if (p2) {
+                                               (currentheader[headerlines] + (p2 - s))[1] = '\n';
+                                               (currentheader[headerlines] + (p2 - s))[2] = 0;
+                                       } else {
+                                               currentheader[headerlines][l] = '\r';
+                                               currentheader[headerlines][l + 1] = '\n';
+                                               currentheader[headerlines][l + 2] = 0;
+                                       }
+                               }
+                               headerlines++;
+                               headermade = 1;
+                       }
+               }
+       } else {
+               if (headerfirstline)
+                       free(headerfirstline);
+               headerfirstline = malloc(l + 3);
+               if (headerfirstline) {
+                       strcpy(headerfirstline, s);
+                       if (!p3) {
+                               if (p2) {
+                                       (headerfirstline + (p2 - s))[1] = '\n';
+                                       (headerfirstline + (p2 - s))[2] = 0;
+                               } else {
+                                       headerfirstline[l] = '\r';
+                                       headerfirstline[l + 1] = '\n';
+                                       headerfirstline[l + 2] = 0;
+                               }
+                       }
+               }
+               headermade = 1;
+       }
+}
+
+void fhttpd_flush( /*GLOBAL(php3_rqst)->connection */ void)
+{
+}
+
+PHPAPI void php3_fhttpd_puts(char *s)
+{
+       putlinetoresponse(response, s);
+}
+
+PHPAPI void php3_fhttpd_putc(char c)
+{
+       writetoresponse(response, &c, 1);
+}
+
+PHPAPI int php3_fhttpd_write(char *a, int n)
+{
+       return writetoresponse(response, a, n);
+}
+#endif
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
index 747d1aec84550c14a843b66c6bc3d2f78bc18297..8dedf3d09254a9ff0047f9f784d0df01545f1118 100644 (file)
 #include "ext/msql/php3_msql.h"
 #include "ext/oracle/php3_oci8.h"
 #include "ext/oracle/oracle.h"
-#include "functions/php3_pgsql.h"
-#include "functions/php3_sybase.h"
-#include "functions/php3_sybase-ct.h"
+#include "ext/pgsql/php3_pgsql.h"
+#include "ext/sybase/php3_sybase.h"
+#include "ext/sybase/php3_sybase-ct.h"
 #include "ext/imap/imap.h"
 #include "ext/standard/head.h"
-#include "functions/post.h"
+#include "ext/standard/post.h"
 #include "ext/hyperwave/hw.h"
 #include "ext/filepro/filepro.h"
 #include "ext/db/db.h"
 #include "dl/snmp/php3_snmp.h"
-#include "functions/php3_zlib.h"
+#include "ext/zlib/php3_zlib.h"
 #include "ext/com/php3_COM.h"
-#include "functions/php3_interbase.h"
-#include "functions/php3_xml.h"
-#include "functions/php3_pdf.h"
+#include "ext/interbase/php3_interbase.h"
+#include "ext/xml/php3_xml.h"
+#include "ext/pdf/php3_pdf.h"
 #include "ext/fdf/php3_fdf.h"
-#include "functions/php3_sysvsem.h"
-#include "functions/php3_sysvshm.h"
+#include "ext/sysvsem/php3_sysvsem.h"
+#include "ext/sysvshm/php3_sysvshm.h"
 #include "ext/dav/php3_dav.h"
 
 unsigned char first_arg_force_ref[] = { 1, BYREF_FORCE };
index e247ea054916e756f557afff86270da310910a2a..0150bb6a3396b8e3f4917a68e18a66e88820624f 100644 (file)
@@ -68,8 +68,6 @@
 #include "control_structures.h"
 #include "fopen-wrappers.h"
 #include "ext/standard/php3_standard.h"
-#include "functions/post.h"
-#include "ext/standard/head.h"
 #include "snprintf.h"
 #if WIN32|WINNT
 #include <io.h>
diff --git a/setup b/setup
index 18a1673f5eac57c424ba421b5b0863e1568f6270..2b7a333d935ac4d9d6388c005bc963ef96dccb59 100644 (file)
--- a/setup
+++ b/setup
@@ -239,50 +239,6 @@ for stub in ext/*/setup.stub; do
     test -f $stub && . $stub
 done
 
-define_option with-sybase 'Sybase support?' yesnodir \
-    'no /home/sybase Sybase install' \
-'     Whether to build PHP with Sybase support (DBLib only).\n
-     More info about Sybase can be found at http://www.sybase.com/.'
-
-define_option with-sybase-ct 'Sybase-CT support?' yesnodir \
-    'no /home/sybase Sybase-CT install' \
-'     Whether to build PHP with Sybase-CT support.'
-
-define_option with-pgsql 'PostgreSQL support?' yesnodir \
-    'no /usr/local/pgsql PostgreSQL base install' \
-'    Whether to build PHP with PostgreSQL support.\n
-    More info about PostgreSQL can be found at\n
-    http://www.postgreSQL.org/.'
-
-define_option with-informix 'Informix support?' yesnodir \
-    "no $INFORMIXDIR Informix home" \
-'    Whether to build PHP with Informix support. If you have not set up your\n
-    Informix environment, enter what $INFORMIXDIR is usually set to here.\n
-    You MUST set $INFORMIXDIR before trying to compile!\n
-    More info about Informix can be found at http://www.informix.com/.'
-
-define_option with-interbase 'InterBase support?' yesnodir \
-    'no /usr/interbase InterBase base install' \
-'     Whether to build PHP with InterBase support. More\n
-      information about InterBase can be found at http://www.interbase.com/.'
-
-define_option with-pdflib 'pdflib 0.6 support? ' yesnodir \
-    'no /usr/local pdflib install' \
-'    Whether to use the pdflib support to write .pdf-files.\n
-    Tested for version 0.6!'
-
-define_option with-zlib 'zlib (>= 1.0.9) support? ' yesnodir \
-    'no /usr zlib install' \
-'    Whether to use the zlib support to read/write .gz-files.\n
-    Requires zlib version >= 1.0.9!'
-
-define_option enable-sysvshm 'System V shared memory support? ' yesno no \
-'    Whether to use the System V shared memory (currently only solaris and linux).'
-
-define_option enable-sysvsem 'System V semaphores support? ' yesno no \
-'    Whether to use the System V semaphores (currently only solaris and linux).'
-
-
 define_option with-config-file-path 'Default config directory?' yesnodir \
     'no /usr/local/lib Configuration file' \
 '    Directory where the PHP3 configuration file (php3.ini) is\n