manoj 99/06/09 23:26:49
Modified: pthreads ABOUT_APACHE Announcement INSTALL KEYS Makefile.tmpl README.NT config.layout configure pthreads/conf highperformance.conf-dist httpd.conf-dist httpd.conf-dist-win mime.types pthreads/src Apache.dsp Apache.mak CHANGES Configuration.tmpl Configure Makefile.nt Makefile.tmpl Makefile_win32.txt Makefile_win32_debug.txt pthreads/src/ap Makefile.tmpl ap_md5c.c ap_snprintf.c pthreads/src/helpers GuessOS PrintPath TestCompile binbuild.sh buildinfo.sh checkheader.sh dummy.c findcpp.sh fmn.sh install.sh mkshadow.sh ppl.sh slo.sh pthreads/src/include alloc.h ap.h ap_compat.h ap_config.h ap_md5.h ap_mmn.h hsregex.h http_config.h http_core.h http_protocol.h httpd.h scoreboard.h util_md5.h pthreads/src/main acceptlock.c alloc.c http_accept.c http_config.c http_core.c http_log.c http_main.c http_protocol.c http_request.c util.c util_md5.c util_script.c util_uri.c pthreads/src/modules/example mod_example.c pthreads/src/modules/proxy .cvsignore Makefile.tmpl proxy_cache.c proxy_connect.c proxy_ftp.c proxy_http.c proxy_util.c pthreads/src/modules/standard .cvsignore mod_alias.c mod_auth_dbm.c mod_autoindex.c mod_cgi.c mod_dir.c mod_env.c mod_imap.c mod_include.c mod_info.c mod_log_config.c mod_mime.c mod_mime_magic.c mod_negotiation.c mod_rewrite.c mod_rewrite.h mod_setenvif.c mod_so.c mod_status.c mod_usertrack.c pthreads/src/modules/test mod_test_util_uri.c pthreads/src/os/bs2000 os.h pthreads/src/os/os2 Makefile.tmpl os.c os.h util_os2.c pthreads/src/os/tpf Makefile.tmpl os.c os.h pthreads/src/os/unix os.c os.h pthreads/src/os/win32 os.h registry.c registry.h service.c service.h pthreads/src/os/win32/installer apache.iwz pthreads/src/support ab.c apachectl apxs.8 htdigest.c htpasswd.1 htpasswd.c httpd.exp log_server_status Added: pthreads/src/ap ap_getpass.c pthreads/src/helpers getuid.sh pthreads/src/lib .cvsignore pthreads/src/lib/expat-lite .cvsignore CHANGES Makefile.tmpl asciitab.h expat.html hashtable.c hashtable.h iasciitab.h latin1tab.h nametab.h utf8tab.h xmldef.h xmlparse.c xmlparse.h xmlrole.c xmlrole.h xmltok.c xmltok.h xmltok_impl.c xmltok_impl.h xmltok_ns.c pthreads/src/support README ab.8 Removed: pthreads/src/support ab.1 Log: Resync the hybrid server with the apache-1.3 repository, as of Wed Jun 9 23:17:22 PDT 1999. Revision Changes Path 1.3 +1 -1 apache-apr/pthreads/ABOUT_APACHE Index: ABOUT_APACHE =================================================================== RCS file: /home/cvs/apache-apr/pthreads/ABOUT_APACHE,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- ABOUT_APACHE 1999/03/17 16:59:14 1.2 +++ ABOUT_APACHE 1999/06/10 06:25:33 1.3 @@ -85,7 +85,7 @@ Alexei Kosut Stanford University, California Martin Kraemer Munich, Germany Ben Laurie Freelance Consultant, UK - Doug MacEachern Freelance Consultant, Summer Seasons, Earth + Doug MacEachern Critical Path, California Aram W. Mirzadeh Qosina Corporation, New York Sameer Parekh C2Net, California Cliff Skolnick Freelance, California 1.3 +59 -25 apache-apr/pthreads/Announcement Index: Announcement =================================================================== RCS file: /home/cvs/apache-apr/pthreads/Announcement,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- Announcement 1999/02/07 06:28:58 1.2 +++ Announcement 1999/06/10 06:25:33 1.3 @@ -1,39 +1,73 @@ -Apache 1.3.4 Released +Apache 1.3.6 Released ===================== The Apache Group is pleased to announce the release of version -1.3.4 of the Apache HTTP server. +1.3.6 of the Apache HTTP server. -This new Apache version incorporates over 90 significant improvements -to the server, including avoidance of some denial-of-service attacks, -support for 3rd-party WebDAV modules, a complete overhaul of content -negotiation, optional column sorting for fancy indexes, the ability to -set a DefaultLanguage, and many fixes to improve consistency, portability, -and squish bugs. A complete listing is provided in the src/CHANGES file. +This new Apache version incorporates over 60 significant improvements +to the server. Apart from portability and security fixes, documentation +enhancements, performance improvements, and assorted other minor +features or fixes notable changes are: -Of special note are the many changes to the Apache configuration process. -The default path layout generated by the "configure" script has been -changed to be more consistent with the traditional Apache layout, and -several new command-line options have been added to make compilation -easier. Please see the README.configure and INSTALL files for complete -information. In addition, we have moved all of the server configuration -directives to a single file (httpd.conf-dist), updated mime.types, and -improved the examples for first-time installers. Finally, a few of the -rarely-used command-line options for httpd have been changed to be more -consistent with the help options of other programs. + - mod_log_config now supports conditional logging based upon + environment variables and support for multiline entries. -We consider Apache 1.3.4 to be the best version of Apache available and + - New CustomLog directive %V: This logs the hostname according to the + UseCanonicalName setting (this is the pre-1.3.4 behaviour of %v). + + - Enhanced mod_rewrite's mapfile handling: The in-core cache for text + and DBM format mapfiles now uses a hash table with LRU functionality. + Furthermore map lookups for non-existent keys are now cached as well. + The changes drastically improve the performance when large rewrite + maps are in use. + + - Ability to handle DES or MD5 authentication passwords. + + - New <LimitExcept> directive to allow the user to assign authentication + control to any HTTP method that is *not* given in the argument list; + i.e., the logical negation of the <Limit> directive. + + - Improved content negotiation. + + - New ScriptInterpreterSource directive to enable searching the + Win32 registry for script interpreters. + + - The FAQ document was reorganised. + + - Overhauled ApacheBench benchmark program. + + - Several new API functions have been added. + +A complete listing with detailed descriptions is provided in the +src/CHANGES file. + +We consider Apache 1.3.6 to be the best version of Apache available and we strongly recommend that users of older versions, especially of the 1.1.x and 1.2.x family, upgrade as soon as possible. No further releases will be made in the 1.2.x family. -Apache 1.3.4 is available for download from + +Apache 1.3.6 is available for download from http://www.apache.org/dist/ Please see the CHANGES_1.3 file in the same directory for a full -list of changes. The distribution is also available via any of -the mirrors listed at +list of changes. + +Binary distributions are available from + + http://www.apache.org/dist/binaries/ + +As of Apache 1.3.6 binary distributions contain all standard Apache +modules as shared objects (if supported by the platform) and include +full source code. Installation is easily done by executing the +included install script. See the README.bindist and INSTALL.bindist +files for a complete explanation. Please note that the binary +distributions are only provided for your convenience and current +distributions for specific platforms are not always available. + +The source and binary distributions are also available via any of the +mirrors listed at http://www.apache.org/mirrors/ @@ -43,8 +77,8 @@ In general, Apache 1.3 offers several substantial improvements over version 1.2, including better performance, reliability and a -wider range of supported platforms, including Windows 95 and NT -(which both fall under the "Win32" label). +wider range of supported platforms, including Windows 95/98 and NT +(which fall under the "Win32" label). Apache is the most popular web server in the known universe; over half of the servers on the Internet are running Apache or one of 1.4 +11 -5 apache-apr/pthreads/INSTALL Index: INSTALL =================================================================== RCS file: /home/cvs/apache-apr/pthreads/INSTALL,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- INSTALL 1999/03/17 16:59:16 1.3 +++ INSTALL 1999/06/10 06:25:33 1.4 @@ -79,11 +79,11 @@ platform-dependent. The current state is this: o Out-of-the-box supported platforms are: - - Linux - SunOS - UnixWare - - FreeBSD - Solaris - AIX - - OpenBSD - IRIX - SCO - - NetBSD - HPUX - - BSDI - Digital Unix + - Linux - SunOS - UnixWare - Mac OS X Server + - FreeBSD - Solaris - AIX - Mac OS + - OpenBSD - IRIX - SCO - OpenStep/Mach + - NetBSD - HPUX - ReliantUNIX + - BSDI - Digital Unix o Entirely unsupported platforms are: - Ultrix @@ -159,6 +159,7 @@ [--with-perl=FILE] [--suexec-uidmin=UID] [--without-support] [--suexec-gidmin=GID] [--without-confadjust] [--suexec-safepath=PATH] + [--without-execstrip] Use the CC, OPTIM, CFLAGS, INCLUDES, LDFLAGS, LIBS, CFLAGS_SHLIB, LD_SHLIB, LDFLAGS_SHLIB, LDFLAGS_SHLIB_EXPORT, RANLIB, DEPS and TARGET @@ -370,6 +371,11 @@ user/situation dependent adjustments to the config files (Group, Port, ServerAdmin, ServerName, etc.). This is usually only interesting for vendor package maintainers who wants to force the keeping of defaults. + + Use the --without-execstrip option to disable the stripping of + executables on installation. This can be important on some platforms in + combination with --enable-rule=SHARED_CORE or when Apache was built with + debugging symbols which shouldn't be lost. Use the --enable-suexec option to enable the suEXEC feature by building and installing the "suexec" support program. Use --suexec-caller=UID to 1.3 +35 -0 apache-apr/pthreads/KEYS Index: KEYS =================================================================== RCS file: /home/cvs/apache-apr/pthreads/KEYS,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- KEYS 1999/02/07 06:28:58 1.2 +++ KEYS 1999/06/10 06:25:34 1.3 @@ -84,6 +84,41 @@ =pwim -----END PGP PUBLIC KEY BLOCK----- +Type Bits KeyID Created Expires Algorithm Use +sec 1024 0x08C975E5 1999-04-14 ---------- DSS Sign & Encrypt +sub 2048 0x4CCDB430 1999-04-14 ---------- Diffie-Hellman +uid Jim Jagielski <[EMAIL PROTECTED]> + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: PGPfreeware 5.5.3i + +mQGiBDcUl9QRBADl5tF8kOD0uddlnl9qsaG70/hwujGTsSXATnqoLseTsWORoVXf +oBklokEAGmT2+Cl8XIXZ31Wh+GaJ3CTbEv8Ok1vapOt+ltPgOKzZEB4uP25EbhC2 +LWf+lUoafcd2Xi0KBV4fqXqEEuDGP1TAdZ6k7NVqgpjvbJ5TdqL0LrWOOwCg/0b4 ++/p/avQr+uZRU2rdmYu/b/0D/2LnjcEqUjsslh2e9m0OgAu+gnYAmQH6Dbnp+iKl +jffWPChwIMFZd/7FnGOzYDzoqnzTFyA4VE5PHWL61V2lpHJWB21K9D6rbEcx0iYB +AHHxZQEmxSBU6PmGnbF+2P7vC0Jz9gZ5dCbjtGboYxd00/XQlZwCs8jHueTpSfx9 +n7dYBACFpW+v2pSlG0ReiS6Ult3gaGWiw81D0nFVvCp5BlxgQDymyF1MS6FbCj/g +FGILosMhlsIHTFaC0DD0LSXyN1rm0ykPvi+vULIlKNJwW7fCi+33j1Azx+zfMNeO +T5vqAfF6cvsZ6qPb9CcYvU4jEKvkovA1U3jMFehqcGkTV5sfvbQeSmltIEphZ2ll +bHNraSA8amltQGFwYWNoZS5vcmc+iQBLBBARAgALBQI3FJfUBAsDAgEACgkQizpg +HwjJdeU/8ACg3mtYerA7QN/8Okp2IgGr+ge4yKgAn09RX5UR8DyZ1/Q8OFasE6T6 +Tg2UuQINBDcUl9UQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1aj +FOmPQFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZ +zf24rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI +/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjT +NP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AK +UJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICCACEhzcRGEc3y3/4YNaG +89FmtIRpFU5zoaZxxDrmUiS1HdhqFykv8ozaTyjfImCuhq8i6DG15oGudxPma7Ey +sCcA/qmQEBVrXFK2DYTFW3UnPyqiE822plo0d45u1csKzPvGpHYVGC4HOEKCghRy +/54nH0fsKV3VSlIXAhRG3LIstzAtslrSYELW1Lov53GK+YZpRDJTbLAxjIYB8kEY +hiQYzHm/cbBeRpjG9BpoBQh54dNOj22CU8HC4KvZSnDcLAzmDyrQFXFfffvJtQ7+ +HH2iIWKMFOjpRHh2ZK6uhJb03Yo/v+admKs1HSEFdV5VJUCkqymhKT0OiWnXmNHq +QUfliQBGBBgRAgAGBQI3FJfVAAoJEIs6YB8IyXXlME4AniogMeV3YLNf6C1Y2+k8 +F3rt0S/OAKDHF+wfxLDzCxsoQbwesIUAKgb7Hg== +=mrXV +-----END PGP PUBLIC KEY BLOCK----- + Type Bits/KeyID Date User ID pub 2048/DD919C31 1996/12/24 [EMAIL PROTECTED] 1.4 +75 -19 apache-apr/pthreads/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/Makefile.tmpl,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- Makefile.tmpl 1999/03/17 16:59:16 1.3 +++ Makefile.tmpl 1999/06/10 06:25:34 1.4 @@ -67,7 +67,7 @@ ## ================================================================== # safe environment -SHELL = /bin/sh +SHELL = @SHELL@ # paths to the source tree parts TOP = . @@ -81,11 +81,11 @@ RM = rm -f MKDIR = $(TOP)/$(AUX)/mkdir.sh INSTALL = $(TOP)/$(AUX)/install.sh -c -IFLAGS_PROGRAM = -m 755 -s -IFLAGS_CORE = -m 755 -IFLAGS_DSO = -m 755 -IFLAGS_SCRIPT = -m 755 -IFLAGS_DATA = -m 644 +IFLAGS_PROGRAM = @IFLAGS_PROGRAM@ +IFLAGS_CORE = @IFLAGS_CORE@ +IFLAGS_DSO = @IFLAGS_DSO@ +IFLAGS_SCRIPT = @IFLAGS_SCRIPT@ +IFLAGS_DATA = @IFLAGS_DATA@ INSTALL_PROGRAM = $(INSTALL) $(IFLAGS_PROGRAM) INSTALL_CORE = $(INSTALL) $(IFLAGS_CORE) INSTALL_DSO = $(INSTALL) $(IFLAGS_DSO) @@ -112,9 +112,9 @@ mandir = @mandir@ sysconfdir = @sysconfdir@ datadir = @datadir@ -iconsdir = $(datadir)/icons -htdocsdir = $(datadir)/htdocs -cgidir = $(datadir)/cgi-bin +iconsdir = @iconsdir@ +htdocsdir = @htdocsdir@ +cgidir = @cgidir@ includedir = @includedir@ localstatedir = @localstatedir@ runtimedir = @runtimedir@ @@ -134,6 +134,7 @@ suexec_safepath = @suexec_safepath@ # some substituted configuration parameters +conf_user = @conf_user@ conf_group = @conf_group@ conf_port = @conf_port@ conf_serveradmin = @conf_serveradmin@ @@ -163,7 +164,9 @@ build: @echo "===> $(SRC)" @$(MAKE) -f $(TOP)/$(MKF) $(MFLAGS) $(MFWD) build-std - @$(MAKE) -f $(TOP)/$(MKF) $(MFLAGS) $(MFWD) $(build-support) + @if [ "x$(build-support)" != "x" ]; then \ + $(MAKE) -f $(TOP)/$(MKF) $(MFLAGS) $(MFWD) $(build-support); \ + fi @touch $(TOP)/$(SRC)/.apaci.build.ok @echo "<=== $(SRC)" @@ -188,8 +191,7 @@ -DUSERDIR_SUFFIX=\"$(suexec_userdir)\" \ -DLOG_EXEC=\"$(suexec_logexec)\" \ -DDOC_ROOT=\"$(suexec_docroot)\" \ - -DSAFE_PATH=\"$(suexec_safepath)\" \ - ' \ + -DSAFE_PATH=\"$(suexec_safepath)\" ' \ suexec; \ fi; \ echo "<=== $(SRC)/support" @@ -198,10 +200,14 @@ ## Installation Targets ## ------------------------------------------------------------------ +# indirection step to avoid conflict with INSTALL document +# on case-insenstive filesystems, for instance on OS/2 +install: install-all + # the install target for installing the complete Apache # package. This is implemented by running subtargets for the # separate parts of the installation process. -install: +install-all: @if [ ! -f $(TOP)/$(SRC)/.apaci.build.ok ]; then \ $(MAKE) -f $(TOP)/$(MKF) $(MFLAGS) $(MFWD) build; \ else \ @@ -238,7 +244,7 @@ # the non-verbose variant for package maintainers install-quiet: - @$(MAKE) -f $(TOP)/$(MKF) $(MFLAGS) $(MFWD) QUIET=1 install + @$(MAKE) -f $(TOP)/$(MKF) $(MFLAGS) $(MFWD) QUIET=1 install-all # create the installation tree install-mktree: @@ -256,6 +262,12 @@ $(MKDIR) $(root)$(runtimedir) $(MKDIR) $(root)$(logfiledir) $(MKDIR) $(root)$(proxycachedir) + [EMAIL PROTECTED] [ "x`$(AUX)/getuid.sh`" = "x0" ]; then \ + echo "chown $(conf_user) $(root)$(proxycachedir)"; \ + chown $(conf_user) $(root)$(proxycachedir); \ + echo "chgrp $(conf_group) $(root)$(proxycachedir)"; \ + chgrp $(conf_group) $(root)$(proxycachedir); \ + fi @echo "<=== [mktree]" # install the server program and optionally corresponding @@ -363,11 +375,54 @@ fi @echo "<=== [support]" +# install the support programs and scripts for binary distribution +install-binsupport: + @echo "===> [support: Installing Apache support programs and scripts for binary distribution]" + $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/ab $(root)$(sbindir)/ab + $(INSTALL_DATA) $(TOP)/$(SRC)/support/ab.8 $(root)$(mandir)/man8/ab.8 + @if [ ".$(TARGET)" = .httpd ]; then \ + apachectl='apachectl'; \ + else \ + apachectl="$(TARGET)ctl"; \ + fi; \ + echo "$(INSTALL_SCRIPT) $(TOP)/$(SRC)/support/apachectl[*] $(root)$(sbindir)/$${apachectl}"; \ + sed -e 's;PIDFILE=.*;PIDFILE=$(runtimedir)/$(TARGET).pid;' \ + -e 's;HTTPD=.*;HTTPD=$(sbindir)/$(TARGET);' \ + < $(TOP)/$(SRC)/support/apachectl > $(TOP)/$(SRC)/.apaci.install.tmp && \ + $(INSTALL_SCRIPT) $(TOP)/$(SRC)/.apaci.install.tmp $(root)$(sbindir)/$${apachectl}; \ + echo "$(INSTALL_DATA) $(TOP)/$(SRC)/support/apachectl.8 $(root)$(mandir)/man8/$${apachectl}.8"; \ + $(INSTALL_DATA) $(TOP)/$(SRC)/support/apachectl.8 $(root)$(mandir)/man8/$${apachectl}.8 + $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/htpasswd $(root)$(bindir)/htpasswd + $(INSTALL_DATA) $(TOP)/$(SRC)/support/htpasswd.1 $(root)$(mandir)/man1/htpasswd.1 + $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/htdigest $(root)$(bindir)/htdigest + $(INSTALL_DATA) $(TOP)/$(SRC)/support/htdigest.1 $(root)$(mandir)/man1/htdigest.1 + @echo "$(INSTALL_SCRIPT) $(TOP)/$(SRC)/support/dbmmanage[*] $(root)$(bindir)/dbmmanage"; \ + $(INSTALL_SCRIPT) $(TOP)/$(SRC)/support/dbmmanage $(root)$(bindir)/dbmmanage + $(INSTALL_DATA) $(TOP)/$(SRC)/support/dbmmanage.1 $(root)$(mandir)/man1/dbmmanage.1 + $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/logresolve $(root)$(sbindir)/logresolve + $(INSTALL_DATA) $(TOP)/$(SRC)/support/logresolve.8 $(root)$(mandir)/man8/logresolve.8 + $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/rotatelogs $(root)$(sbindir)/rotatelogs + $(INSTALL_DATA) $(TOP)/$(SRC)/support/rotatelogs.8 $(root)$(mandir)/man8/rotatelogs.8 + @echo "$(INSTALL_SCRIPT) $(TOP)/$(SRC)/support/apxs[*] $(root)$(sbindir)/apxs"; \ + $(INSTALL_SCRIPT) $(TOP)/$(SRC)/support/apxs $(root)$(sbindir)/apxs + $(INSTALL_DATA) $(TOP)/$(SRC)/support/apxs.8 $(root)$(mandir)/man8/apxs.8 + [EMAIL PROTECTED] [ ".$(suexec)" = .1 ]; then \ + echo "$(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/suexec $(root)$(sbindir)/suexec"; \ + $(INSTALL_PROGRAM) $(TOP)/$(SRC)/support/suexec $(root)$(sbindir)/suexec; \ + echo "chown root $(root)$(sbindir)/suexec"; \ + chown root $(root)$(sbindir)/suexec; \ + echo "chmod 4711 $(root)$(sbindir)/suexec"; \ + chmod 4711 $(root)$(sbindir)/suexec; \ + echo "$(INSTALL_DATA) $(TOP)/$(SRC)/support/suexec.8 $(root)$(mandir)/man8/suexec.8"; \ + $(INSTALL_DATA) $(TOP)/$(SRC)/support/suexec.8 $(root)$(mandir)/man8/suexec.8; \ + fi + @echo "<=== [support]" + # install the Apache C header files install-include: @echo "===> [include: Installing Apache C header files]" $(CP) $(TOP)/$(SRC)/include/*.h $(root)$(includedir)/ - @osdir=`grep '^OSDIR=' $(TOP)/$(SRC)/Makefile.config | sed -e 's:^OSDIR=.*/os:os:'`; \ + @osdir=`grep '^OSDIR=' $(TOP)/$(SRC)/Makefile.config | sed -e 's:^OSDIR=.*/os/:os/:'`; \ echo "$(CP) $(TOP)/$(SRC)/$${osdir}/os.h $(root)$(includedir)/"; \ $(CP) $(TOP)/$(SRC)/$${osdir}/os.h $(root)$(includedir)/; \ echo "$(CP) $(TOP)/$(SRC)/$${osdir}/os-inline.c $(root)$(includedir)/"; \ @@ -432,16 +487,17 @@ -e 's;@@ServerRoot@@/cgi-bin;$(cgidir);' \ -e 's;@@ServerRoot@@/proxy;$(proxycachedir);' \ -e 's;@@ServerRoot@@;$(prefix);g' \ - -e 's;httpd.conf;$(TARGET).conf;' \ - -e 's;logs/accept.lock;$(runtimedir)/$(TARGET).lock;' \ + -e 's;httpd\.conf;$(TARGET).conf;' \ + -e 's;logs/accept\.lock;$(runtimedir)/$(TARGET).lock;' \ -e 's;logs/apache_runtime_status;$(runtimedir)/$(TARGET).scoreboard;' \ - -e 's;logs/httpd.pid;$(runtimedir)/$(TARGET).pid;' \ + -e 's;logs/httpd\.pid;$(runtimedir)/$(TARGET).pid;' \ -e "s;logs/access_log;$(logfiledir)/$${target_prefix}access_log;" \ -e "s;logs/error_log;$(logfiledir)/$${target_prefix}error_log;" \ -e "s;logs/referer_log;$(logfiledir)/$${target_prefix}referer_log;" \ -e "s;logs/agent_log;$(logfiledir)/$${target_prefix}agent_log;" \ -e 's;conf/magic;$(sysconfdir)/magic;' \ - -e 's;conf/mime.types;$(sysconfdir)/mime.types;' \ + -e 's;conf/mime\.types;$(sysconfdir)/mime.types;' \ + -e 's;User nobody;User $(conf_user);' \ -e 's;Group #-1;Group $(conf_group);' \ -e 's;Port 80;Port $(conf_port);' \ -e 's;ServerAdmin [EMAIL PROTECTED];ServerAdmin $(conf_serveradmin);' \ 1.2 +66 -70 apache-apr/pthreads/README.NT Index: README.NT =================================================================== RCS file: /home/cvs/apache-apr/pthreads/README.NT,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- README.NT 1999/01/21 23:08:29 1.1 +++ README.NT 1999/06/10 06:25:34 1.2 @@ -1,95 +1,91 @@ - Apache for Windows - Version 1.3 (and up) - -What is it? ------------ -Apache is an HTTP server, originally designed for Unix systems. This -is the first major release of Apache for Windows systems, including -Microsoft Windows NT, 98, and 95. Like the Unix version, it includes -many frequently requested new features, and has an API that allows it -to be extended to meet users' needs more easily. It also allows ISAPI -extensions. - -Documentation -------------- + Apache + Version 1.3 (and up) -The documentation available as of the date of this release is also -included, in HTML format, in the <./htdocs/manual/> directory. -For the most up-to-date documentation, visit us on the WWW at -<http://www.apache.org/>. For Windows specific information, see -<http://www.apache.org/docs/windows.html>. + What is it? + ----------- -WARNING -------- + Apache is an HTTP server, originally designed for Unix systems. This + is the version of Apache for Microsoft Windows NT, 98, and 95 + systems. Like the Unix version, it includes many frequently + requested new features, and has an API that allows it to be extended + to meet users' needs more easily. It also allows ISAPI extensions. -Apache on Win32 has not yet been optimized for performance. Apache still -performs best, and is most reliable on Unix platforms. Over time we -will improve performance for Windows NT. Folks doing comparative reviews -of webserver performance are asked to compare against Apache on a Unix -platform such as Solaris, FreeBSD, or Linux. -Apache on Win32 should still be considered beta quality code. It does not -meet the normal standards of stability and security that Unix releases do. + The Latest Version + ------------------ -Installation or Compilation Instructions ----------------------------------------- + Details of the latest version can be found on the Apache HTTP + server project page under http://www.apache.org/. -See the website <http://www.apache.org/docs/windows.html> for details of -how to install Apache from a binary release or how to compile Apache -from scratch. This file is also included in the distribution as -<./htdocs/manual/windows.html>. + Documentation + ------------- -Known Problems --------------- + The documentation available as of the date of this release is + also included, in HTML format, in the htdocs/manual/ directory. + For the most up-to-date documentation can be found on + http://www.apache.org/docs/. For Windows specific information, see + http://www.apache.org/docs/windows.html. -To get information about the current set of known problems, see our -online bug reporting database at <http://www.apache.org/bug_report.html>. -In particular, search for problem reports under the category "os-windows". + WARNING + ------- -This is a rough list of what we know has not been implemented on Win32. + Apache on Win32 has not yet been optimized for performance. Apache + still performs best, and is most reliable on Unix platforms. Over + time we will improve performance for Windows NT. Folks doing + comparative reviews of webserver performance are asked to compare + against Apache on a Unix platform such as Solaris, FreeBSD, or + Linux. -- The User directive is not supported. If you run apache as a service, - you can change the user it runs as by going to - Control Panel->Services->Startup + Apache on Win32 should still be considered beta quality code. It + does not meet the normal standards of stability and security that + Unix releases do. -- suexec doesn't work + Installation + ------------ -- RFC 1413 (IdentityCheck) is not yet ported + If you have installed Apache as a pre-compiled binary, you can + now run the server by selecting "Start Apache as console app" + from the Start menu. You can configure Apache for your system + by editing the file conf/httpd.conf in the directory where you + installed Apache. -- If you have a very busy server, when a server child process exits, - any connections made to that child process that have not yet been - accepted by it are aborted. + See the http://www.apache.org/docs/windows.html for details of how + to run and configure Apache, or select the "Apache Documentation" + icon read the local copy installed with Apache. -- The regex library build does not generate *.ih headers. + Known Problems + -------------- -- Multithreading is not properly abstracted + To get information about the current set of known problems, see the + online bug reporting database at + http://www.apache.org/bug_report.html. Bugs which affect Apache on + Windows and not Apache on Unix can be found under the category + "os-windows". -- htpasswd passwords are stored in plain text because Windows lacks a - crypt() function + Licensing + --------- -Licensing ---------- + Please see the file called LICENSE. -Please see the file called LICENSE. + Acknowledgments + ---------------- -Acknowledgments ----------------- + We wish to acknowledge the following copyrighted works that + make up portions of the Apache software: -We wish to acknowledge the following copyrighted works that make up -portions of the Apache software: + Portions of this software were developed at the National Center + for Supercomputing Applications (NCSA) at the University of + Illinois at Urbana-Champaign. -Portions of this software were developed at the National Center for -Supercomputing Applications at the University of Illinois at -Urbana-Champaign. + This software contains code derived from the RSA Data Security + Inc. MD5 Message-Digest Algorithm, including various + modifications by Spyglass Inc., Carnegie Mellon University, and + Bell Communications Research, Inc (Bellcore). -This software contains code derived from the RSA Data Security Inc. MD5 -Message-Digest Algorithm, including various modifications by Spyglass Inc., -Carnegie Mellon University, and Bell Communications Research, Inc. -(Bellcore). + This package contains software written and copyrighted by Henry + Spencer. Please see the file called src/regex/COPYRIGHT. -This package contains software written and copyrighted by Henry Spencer. -Please see the file called src/regex/COPYRIGHT. + The NT port was started with code provided to the Apache Group + by Ambarish Malpani of ValiCert, Inc. (http://www.valicert.com/). -The NT port was started with code provided to the Apache Group -by Ambarish Malpani of ValiCert, Inc. (www.valicert.com). 1.3 +57 -5 apache-apr/pthreads/config.layout Index: config.layout =================================================================== RCS file: /home/cvs/apache-apr/pthreads/config.layout,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- config.layout 1999/03/17 16:59:19 1.2 +++ config.layout 1999/06/10 06:25:34 1.3 @@ -19,6 +19,9 @@ mandir: $prefix/man sysconfdir: $prefix/conf datadir: $prefix + iconsdir: $datadir/icons + htdocsdir: $datadir/htdocs + cgidir: $datadir/cgi-bin includedir: $prefix/include localstatedir: $prefix runtimedir: $localstatedir/logs @@ -37,6 +40,9 @@ mandir: $prefix/man sysconfdir: $prefix/etc+ datadir: $prefix/share+ + iconsdir: $datadir/icons + htdocsdir: $datadir/htdocs + cgidir: $datadir/cgi-bin includedir: $prefix/include+ localstatedir: $prefix/var+ runtimedir: $localstatedir/run @@ -54,6 +60,9 @@ mandir: man sysconfdir: conf datadir: + iconsdir: icons + htdocsdir: htdocs + cgidir: cgi-bin includedir: include localstatedir: runtimedir: logs @@ -62,18 +71,61 @@ </Layout> # Apple's Mac OS X Server Layout -<Layout Rhapsody> +<Layout Mac OS X Server> prefix: /Local/Library/WebServer - exec_prefix: /usr + exec_prefix: /usr/local bindir: $exec_prefix/bin sbindir: $exec_prefix/sbin - libexecdir: /System/Library/Apache/Modules + libexecdir: /Local/Library/Apache/Modules mandir: $exec_prefix/share/man sysconfdir: $prefix/Configuration datadir: $prefix - includedir: /System/Library/Frameworks/Apache.framework/Versions/1.3/Headers - localstatedir: /private/var + iconsdir: /Local/Library/Apache/Icons + htdocsdir: $datadir/Documents + cgidir: $datadir/CGI-Executables + includedir: /Local/Library/Frameworks/Apache.framework/Versions/1.3/Headers + localstatedir: /var runtimedir: $prefix/Logs logfiledir: $prefix/Logs proxycachedir: $prefix/ProxyCache +</Layout> + +# RedHat 5.x layout +<Layout RedHat> + prefix: /usr + exec_prefix: $prefix + bindir: $prefix/bin + sbindir: $prefix/sbin + libexecdir: $prefix/lib/apache + mandir: $prefix/man + sysconfdir: /etc/httpd/conf + datadir: /home/httpd + iconsdir: $datadir/icons + htdocsdir: $datadir/htdocs + cgidir: $datadir/cgi-bin + includedir: $prefix/include/apache + localstatedir: /var + runtimedir: $localstatedir/run + logfiledir: $localstatedir/log/httpd + proxycachedir: $localstatedir/cache/httpd +</Layout> + +# According to the /opt filesystem conventions +<Layout opt> + prefix: /opt/apache + exec_prefix: $prefix + bindir: $exec_prefix/bin + sbindir: $exec_prefix/sbin + libexecdir: $exec_prefix/libexec + mandir: $prefix/man + sysconfdir: /etc$prefix + datadir: $prefix/share + iconsdir: $datadir/icons + htdocsdir: $datadir/htdocs + cgidir: $datadir/cgi-bin + includedir: $prefix/include + localstatedir: /var$prefix + runtimedir: $localstatedir/run + logfiledir: $localstatedir/logs + proxycachedir: $localstatedir/proxy </Layout> 1.4 +162 -55 apache-apr/pthreads/configure Index: configure =================================================================== RCS file: /home/cvs/apache-apr/pthreads/configure,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- configure 1999/03/17 16:59:19 1.3 +++ configure 1999/06/10 06:25:35 1.4 @@ -66,6 +66,11 @@ ' ## +## avoid brain dead shells on Ultrix and friends +## +test -f /bin/sh5 && exec /bin/sh5 $0 "$@" + +## ## the paths to the Apache source tree ## top=. @@ -87,13 +92,27 @@ quiet=no verbose=no case "$*" in - --help|*--help|*--help* ) help=yes; quiet=yes ;; - --quiet|*--quiet|*--quiet* ) quiet=yes ;; - --verbose|*--verbose|*--verbose*|-v|*-v|*-v* ) verbose=yes ;; - * ) ;; + --help|*--help|*--help* ) + help=yes; quiet=yes + echo "[hang on a moment, generating help]" + echo "" + ;; + --quiet|*--quiet|*--quiet* ) + quiet=yes + ;; + --verbose|*--verbose|*--verbose*|-v|*-v|*-v* ) + verbose=yes + ;; + * ) + ;; esac ## +## determine platform id +## +PLATFORM="`$aux/GuessOS`" + +## ## display version information ## if [ "x$quiet" = "xno" ]; then @@ -157,7 +176,7 @@ fi ## -## Look for a good tar. If we don't find 'GNU tar' then make +## Look for a good Tar. If we don't find 'GNU tar' then make ## sure ours can handle the '-h' (don't copy symlink, copy ## the actual data) option. ## @@ -178,6 +197,18 @@ esac ## +## determine path to sh, it's not /bin/sh on ALL systems +## +SHELL=/bin/sh +if [ ! -f "$SHELL" ]; then + SHELL="`$aux/PrintPath sh`" + if [ "x$SHELL" = "x" ]; then + echo "configure:Error: Cannot determine path to Bourne-Shell" 1>&2 + exit 1 + fi +fi + +## ## determine default parameters ## @@ -199,6 +230,19 @@ suexec_gidmin=100 suexec_safepath="/usr/local/bin:/usr/bin:/bin" +# the installation flags +iflags_program="-m 755 -s" +iflags_core="-m 755" +iflags_dso="-m 755" +iflags_script="-m 755" +iflags_data="-m 644" +case $PLATFORM in + *OS/2* ) + iflags_program="$iflags_program -e .exe" + iflags_core="$iflags_core -e .exe" + ;; +esac + # various other flags support=1 confadjust=1 @@ -207,7 +251,8 @@ # determine rules rules='' rulelist='' -OIFS="$IFS" IFS=' +OIFS="$IFS" +IFS=' ' for rule in `grep '^Rule' $src/Configuration.tmpl`; do rule=`echo "$rule" | sed -e 's/^Rule[ ]*//'` @@ -224,15 +269,16 @@ # determine modules modules='' modulelist='' -OIFS="$IFS" IFS=' +OIFS="$IFS" +IFS=' ' for module in `egrep '^[# ]*(Add|Shared)Module' $src/Configuration.tmpl`; do add=yes share=no - if [ ".`echo $module | grep '^#'`" != . ]; then + if [ "x`echo $module | grep '^#'`" != "x" ]; then add=no fi - if [ ".`echo $module | grep 'SharedModule'`" != . ]; then + if [ "x`echo $module | grep 'SharedModule'`" != "x" ]; then share=yes fi module=`echo "$module" |\ @@ -255,7 +301,8 @@ # backward compatibility for old src/Configuration.tmpl # parameter names to the canonical Autoconf-style shell # variable names. -OIFS="$IFS" IFS="$DIFS" +OIFS="$IFS" +IFS="$DIFS" for var in CFLAGS LDFLAGS LIBS INCLUDES DEPS; do eval "val=\$EXTRA_$var" if [ "x$val" != "x" ]; then @@ -267,6 +314,15 @@ IFS="$OIFS" ## +## Platform-specific defaults +## +case $PLATFORM in + *-apple-rhapsody*) default_layout="Mac OS X Server";; + *-apple-macos*) default_layout="Mac OS X Server";; + *) default_layout="Apache";; +esac + +## ## support for the default layout ## case "$*" in @@ -274,9 +330,9 @@ ;; * ) if [ "x$*" = "x" ]; then - set -- '--with-layout=Apache' + set -- --with-layout="$default_layout" else - set -- '--with-layout=Apache' "$@" + set -- --with-layout="$default_layout" "$@" fi ;; esac @@ -289,7 +345,8 @@ ## can be overridden by others. ## apc_prev='' -OIFS1="$IFS" IFS="$DIFS" +OIFS1="$IFS" +IFS="$DIFS" for apc_option do # if previous option needs an argument, assign it. @@ -349,6 +406,7 @@ echo " --with-perl=FILE path to the optional Perl interpreter" echo " --without-support disable the build and installation of support tools" echo " --without-confadjust disable the user/situation adjustments in config" + echo " --without-execstrip disable the stripping of executables on installation" echo "" echo "suEXEC options:" echo " --enable-suexec enable the suEXEC feature" @@ -390,10 +448,11 @@ -e "s/[ ]*$/'/g" \ $file >$pldconf . $pldconf - OIFS="$IFS" IFS="$DIFS" + OOIFS="$IFS" # most likely not needed: jmj + IFS="$DIFS" # ditto for var in prefix exec_prefix bindir sbindir libexecdir mandir \ - sysconfdir datadir includedir localstatedir runtimedir \ - logfiledir proxycachedir; do + sysconfdir datadir iconsdir htdocsdir cgidir includedir \ + localstatedir runtimedir logfiledir proxycachedir; do eval "val=\"\$$var\"" case $val in *+ ) @@ -406,7 +465,7 @@ ;; esac done - IFS="$OIFS" + IFS="$OOIFS" rm -f $pldconf 2>/dev/null if [ "x$prefix" = "xUNSET" ]; then echo "configure:Error: Path layout definition not found or incorrect" 1>&2 @@ -415,6 +474,7 @@ if [ "x$quiet" = "xno" ]; then echo " + using installation path layout: $name ($file)" fi + name_layout=$name with_layout=1 ;; *) @@ -429,7 +489,6 @@ ## addconf_created=0 apc_prev='' -OIFS1="$IFS" IFS="$DIFS" for apc_option do # if previous option needs an argument, assign it. @@ -476,9 +535,11 @@ ;; esac # determine GNU platform triple - gnutriple=`$aux/GuessOS | sed -e 's:/:-:g' | $AWK '{ printf("%s",$1); }'` + # (the use of `awk' and not `$AWK' here is correct, because this + # Makefile is for platform bootstrapping, so don't hardcode paths) + gnutriple=`$aux/GuessOS | sed -e 's:/:-:g' | awk '{ printf("%s",$1); }'` # create Makefile wrapper (the first time only) - if [ ".`ls $top/src.* 2>/dev/null`" = . ]; then + if [ "x`ls $top/src.* 2>/dev/null`" = "x" ]; then if [ "x$quiet" = "xno" ]; then echo " + creating Makefile (shadow wrapper)" fi @@ -578,7 +639,7 @@ ;; --add-module=*) file="$apc_optarg" - if [ ".`echo $file | egrep '/?mod_[a-zA-Z0-9][a-zA-Z0-9_]*\.c$'`" = . ]; then + if [ "x`echo $file | egrep '/?mod_[a-zA-Z0-9][a-zA-Z0-9_]*\.c$'`" = "x" ]; then echo "configure:Error: Module filename doesn't match '/?mod_[a-zA-Z0-9][a-zA-Z0-9_]*\.c'" 1>&2 exit 1 fi @@ -665,18 +726,20 @@ module ) case $apc_optarg in all ) - OIFS="$IFS" IFS=':' + OOIFS="$IFS" + IFS=':' for module in $modules; do eval "module_${module}=yes" done - IFS="$OIFS" + IFS="$OOIFS" ;; most ) - OIFS="$IFS" IFS=':' + OOIFS="$IFS" + IFS=':' for module in $modules; do eval "module_${module}=yes" done - IFS="$OIFS" + IFS="$OOIFS" module_auth_db=no # not all platforms have -ldb module_mmap_static=no # not all platforms have mmap() module_so=no # not all platforms have dlopen() @@ -697,15 +760,17 @@ shared ) case $apc_optarg in max ) - OIFS="$IFS" IFS=':' + OOIFS="$IFS" + IFS=':' for module in $modules; do eval "shared_${module}=yes" done - IFS="$OIFS" + IFS="$OOIFS" shared_so=no # because of bootstrapping ;; remain ) - OIFS="$IFS" IFS=':' + OOIFS="$IFS" + IFS=':' for module in $modules; do eval "add=\$module_${module}" if [ "x$add" = "xno" ]; then @@ -713,7 +778,7 @@ eval "shared_${module}=yes" fi done - IFS="$OIFS" + IFS="$OOIFS" shared_so=no ;; * ) @@ -756,11 +821,12 @@ module ) case $apc_optarg in all ) - OIFS="$IFS" IFS=':' + OOIFS="$IFS" + IFS=':' for module in $modules; do eval "module_${module}=no" done - IFS="$OIFS" + IFS="$OOIFS" ;; * ) eval "exists=\$module_${apc_optarg}" @@ -775,11 +841,12 @@ shared ) case $apc_optarg in all ) - OIFS="$IFS" IFS=':' + OOIFS="$IFS" + IFS=':' for module in $modules; do eval "shared_${module}=no" done - IFS="$OIFS" + IFS="$OOIFS" ;; * ) eval "exists=\$module_${apc_optarg}" @@ -829,6 +896,9 @@ --without-confadjust) confadjust=0 ;; + --without-execstrip) + iflags_program=`echo "$iflags_program" | sed -e 's/-s//'` + ;; --suexec-caller=*) suexec_caller="$apc_optarg" suexec_ok=1 @@ -920,7 +990,7 @@ echo " and htdocs/manual/suexec.html documents first." exit 1 fi - if [ ".`id | grep root`" = . ]; then + if [ "x`$aux/getuid.sh`" != "x0" ]; then echo " + Warning: You enabled the suEXEC feature. Be aware that you need" 1>&2 echo " + root privileges for this, at the latest at the installation step." 1>&2 fi @@ -936,7 +1006,7 @@ ## target name ## if [ "x$TARGET" != "x" ]; then - thetarget=$TARGET + thetarget="$TARGET" else thetarget=httpd fi @@ -945,10 +1015,12 @@ ## expand path variables and make sure ## they do not end with a backslash ## -OIFS="$IFS" IFS="$DIFS" +OIFS="$IFS" +IFS="$DIFS" for var in prefix exec_prefix bindir sbindir libexecdir mandir \ - sysconfdir datadir includedir localstatedir runtimedir \ - logfiledir proxycachedir suexec_docroot suexec_logexec; do + sysconfdir datadir iconsdir htdocsdir cgidir includedir \ + localstatedir runtimedir logfiledir proxycachedir \ + suexec_docroot suexec_logexec; do eval "val=\"\$$var\""; val=`echo $val | sed -e 's:/*$::'` eval "$var=\"$val\"" @@ -978,7 +1050,11 @@ ## if [ "x$support" = "x1" ]; then build_support='build-support' - install_support='install-support' + if [ "x$name_layout" = "xBinaryDistribution" ]; then + install_support='install-binsupport' + else + install_support='install-support' + fi clean_support='clean-support' distclean_support='distclean-support' else @@ -990,20 +1066,32 @@ ## ## determine special configuration parameters +## +## The checks via /etc/passwd and /etc/group will obviously fail +## on platforms using NIS. But then you propably do not want a +## UID/GID as production oriented as a web server in NIS anyway. ## +conf_user="nobody" conf_group="#-1" conf_port="80" conf_serveradmin="[EMAIL PROTECTED]" conf_servername="new.host.name" if [ "x$confadjust" = "x1" ]; then - if [ ".`egrep '^nobody:' /etc/group`" != . ]; then - conf_group="nobody" - else - if [ ".`egrep '^nogroup:' /etc/group`" != . ]; then - conf_group="nogroup" - fi + if [ -f /etc/passwd ]; then + for uid in nobody www daemon demon http httpd; do + if [ "x`egrep \^${uid}: /etc/passwd`" != "x" ]; then + conf_user="$uid" + break + fi + done + for gid in nobody nogroup www daemon demon http httpd; do + if [ "x`egrep \^${gid}: /etc/group`" != "x" ]; then + conf_group="$gid" + break + fi + done fi - if [ ".`id | grep root`" = . ]; then + if [ "x`$aux/getuid.sh`" != "x0" ]; then conf_port="8080" fi conf_serveradmin="`$aux/buildinfo.sh -n [EMAIL PROTECTED]" @@ -1038,6 +1126,9 @@ echo " mandir: $mandir" echo " sysconfdir: $sysconfdir" echo " datadir: $datadir" + echo " iconsdir: $iconsdir" + echo " htdocsdir: $htdocsdir" + echo " cgidir: $cgidir" echo " includedir: $includedir" echo " localstatedir: $localstatedir" echo " runtimedir: $runtimedir" @@ -1086,6 +1177,11 @@ -e "[EMAIL PROTECTED]@%$mkf%g" \ -e "[EMAIL PROTECTED]@%$aux%g" \ -e "[EMAIL PROTECTED]@%$thetarget%g" \ +-e "[EMAIL PROTECTED]@%$iflags_program%g" \ +-e "[EMAIL PROTECTED]@%$iflags_core%g" \ +-e "[EMAIL PROTECTED]@%$iflags_dso%g" \ +-e "[EMAIL PROTECTED]@%$iflags_script%g" \ +-e "[EMAIL PROTECTED]@%$iflags_data%g" \ -e "[EMAIL PROTECTED]@%$prefix%g" \ -e "[EMAIL PROTECTED]@%$exec_prefix%g" \ -e "[EMAIL PROTECTED]@%$bindir%g" \ @@ -1095,6 +1191,9 @@ -e "[EMAIL PROTECTED]@%$mandir%g" \ -e "[EMAIL PROTECTED]@%$sysconfdir%g" \ -e "[EMAIL PROTECTED]@%$datadir%g" \ +-e "[EMAIL PROTECTED]@%$iconsdir%g" \ +-e "[EMAIL PROTECTED]@%$htdocsdir%g" \ +-e "[EMAIL PROTECTED]@%$cgidir%g" \ -e "[EMAIL PROTECTED]@%$localstatedir%g" \ -e "[EMAIL PROTECTED]@%$includedir%g" \ -e "[EMAIL PROTECTED]@%$runtimedir%g" \ @@ -1108,6 +1207,7 @@ -e "[EMAIL PROTECTED]@%$suexec_uidmin%g" \ -e "[EMAIL PROTECTED]@%$suexec_gidmin%g" \ -e "[EMAIL PROTECTED]@%$suexec_safepath%g" \ +-e "[EMAIL PROTECTED]@%$conf_user%g" \ -e "[EMAIL PROTECTED]@%$conf_group%g" \ -e "[EMAIL PROTECTED]@%$conf_port%g" \ -e "[EMAIL PROTECTED]@%$conf_serveradmin%g" \ @@ -1115,7 +1215,8 @@ -e "[EMAIL PROTECTED]@%$build_support%g" \ -e "[EMAIL PROTECTED]@%$install_support%g" \ -e "[EMAIL PROTECTED]@%$clean_support%g" \ --e "[EMAIL PROTECTED]@%$distclean_support%g" +-e "[EMAIL PROTECTED]@%$distclean_support%g" \ +-e "[EMAIL PROTECTED]@%$SHELL%g" ## ## override default paths in $src/include/httpd.h @@ -1150,7 +1251,8 @@ touch $sedsubst # generate settings from imported environment variables -OIFS="$IFS" IFS="$DIFS" +OIFS="$IFS" +IFS="$DIFS" for var in CC CPP OPTIM CFLAGS CFLAGS_SHLIB LDFLAGS LD_SHLIB LDFLAGS_SHLIB \ LDFLAGS_SHLIB_EXPORT LIBS INCLUDES RANLIB DEPS TARGET; do eval "val=\"\$$var\""; @@ -1169,7 +1271,8 @@ IFS="$OIFS" # generate rule directives -OIFS="$IFS" IFS=':' +OIFS="$IFS" +IFS=':' for rule in $rules; do name="`echo $rule | tr "a-z" "A-Z"`" eval "val=\$rule_$rule" @@ -1182,7 +1285,8 @@ # consistency checks for shared object support some_shares=0 -OIFS="$IFS" IFS=':' +OIFS="$IFS" +IFS=':' for module in $modules; do eval "share=\$shared_$module" if [ "x$share" = "xyes" ]; then @@ -1207,7 +1311,8 @@ # module permutation support if [ "x$permute" != "x" ]; then sed -e '/## mod_mmap_static/,$d' <src/Configuration.tmpl >$tplconf - OIFS="$IFS" IFS=' + OIFS="$IFS" + IFS=' ' for line in `cat src/Configuration.tmpl $addconf | egrep '^[# ]*(Add|Shared)Module'`; do name=`echo "$line" |\ @@ -1277,13 +1382,14 @@ fi # generate module directives -OIFS="$IFS" IFS=':' +OIFS="$IFS" +IFS=':' for module in $modules; do eval "add=\$module_$module" if [ "x$add" = "xyes" ]; then echo $SEO "s%^.*\\(AddModule.*[_b/]$module\\..*\\)%\\1%g" >>$sedsubst echo $SEO "s%^.*\\(SharedModule.*[_b/]$module\\..*\\)%\\1%g" >>$sedsubst - m="yes [static]" + m="yes" else echo $SEO "s%^.*\\(AddModule.*[_b/]$module\\..*\\)%# \\1%g" >>$sedsubst echo $SEO "s%^.*\\(SharedModule.*[_b/]$module\\..*\\)%# \\1%g" >>$sedsubst @@ -1292,7 +1398,7 @@ eval "share=\$shared_$module" if [ "x$share" = "xyes" ]; then echo $SEO "s%^\\(.*\\)AddModule\\(.*[_b/]$module\\.\\)[oam].*\\(.*\\)%\\1SharedModule\\2so\\3%g" >>$sedsubst - m="yes [shared]" + m="$m [shared]" fi if [ "x$verbose" = "xyes" ]; then echo " + Module $module: $m" @@ -1314,7 +1420,8 @@ print $0 >file; } ' "sedsubst=$sedsubst"` -OIFS="$IFS" IFS="$DIFS" +OIFS="$IFS" +IFS="$DIFS" substcmd="" for file in $files; do substcmd="${substcmd} sed -f $file |" 1.3 +2 -1 apache-apr/pthreads/conf/highperformance.conf-dist Index: highperformance.conf-dist =================================================================== RCS file: /home/cvs/apache-apr/pthreads/conf/highperformance.conf-dist,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- highperformance.conf-dist 1999/03/07 00:50:28 1.2 +++ highperformance.conf-dist 1999/06/10 06:25:38 1.3 @@ -18,7 +18,8 @@ StartServers 5 MinSpareServers 5 MaxSpareServers 10 -MaxRequestsPerChild 10000000 +# Assume no memory leaks at all +MaxRequestsPerChild 0 # this is a True Config File # see http://www.apache.org/info/three-config-files.html 1.5 +16 -5 apache-apr/pthreads/conf/httpd.conf-dist Index: httpd.conf-dist =================================================================== RCS file: /home/cvs/apache-apr/pthreads/conf/httpd.conf-dist,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- httpd.conf-dist 1999/03/17 16:59:28 1.4 +++ httpd.conf-dist 1999/06/10 06:25:38 1.5 @@ -165,9 +165,15 @@ # as to avoid problems after prolonged use when Apache (and maybe the # libraries it uses) leak memory or other resources. On most systems, this # isn't really needed, but a few (such as Solaris) do have notable leaks -# in the libraries. +# in the libraries. For these platforms, set to something like 10000 +# or so; a setting of 0 means unlimited. # -MaxRequestsPerChild 30 +# NOTE: This value does not include keepalive requests after the initial +# request per connection. For example, if a child process handles +# an initial request and 10 subsequent "keptalive" requests, it +# would only count as 1 request towards this limit. +# +MaxRequestsPerChild 0 # # Listen: Allows you to bind Apache to specific IP addresses and/or @@ -335,7 +341,7 @@ # Control access to UserDir directories. The following is an example # for a site where these directories are restricted to read-only. # -#<Directory /*/public_html> +#<Directory /home/*/public_html> # AllowOverride FileInfo AuthConfig Limit # Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec # <Limit GET POST OPTIONS PROPFIND> @@ -368,7 +374,10 @@ # .htaccess files. If you change the AccessFileName directive above, # be sure to make the corresponding changes here. # -<Files .htaccess> +# Also, folks tend to use names such as .htpasswd for password +# files, so this will protect those as well. +# +<Files ~ "^\.ht"> Order allow,deny Deny from all </Files> @@ -620,7 +629,7 @@ # to do with the FancyIndexing customization directives above. # AddEncoding x-compress Z -AddEncoding x-gzip gz +AddEncoding x-gzip gz tgz # # AddLanguage allows you to specify the language of a document. You can @@ -653,6 +662,8 @@ # #AddType application/x-httpd-php3 .php3 #AddType application/x-httpd-php3-source .phps + +AddType application/x-tar .tgz # # AddHandler allows you to map certain file extensions to "handlers", 1.4 +3 -1 apache-apr/pthreads/conf/httpd.conf-dist-win Index: httpd.conf-dist-win =================================================================== RCS file: /home/cvs/apache-apr/pthreads/conf/httpd.conf-dist-win,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- httpd.conf-dist-win 1999/03/17 16:59:29 1.3 +++ httpd.conf-dist-win 1999/06/10 06:25:38 1.4 @@ -559,7 +559,7 @@ # to do with the FancyIndexing customisation directives above. # AddEncoding x-compress Z -AddEncoding x-gzip gz +AddEncoding x-gzip gz tgz # # AddLanguage allows you to specify the language of a document. You can @@ -592,6 +592,8 @@ # #AddType application/x-httpd-php3 .phtml #AddType application/x-httpd-php3-source .phps + +AddType application/x-tar .tgz # # AddHandler allows you to map certain file extensions to "handlers", 1.4 +1 -1 apache-apr/pthreads/conf/mime.types Index: mime.types =================================================================== RCS file: /home/cvs/apache-apr/pthreads/conf/mime.types,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- mime.types 1999/03/17 16:59:34 1.3 +++ mime.types 1999/06/10 06:25:38 1.4 @@ -117,7 +117,7 @@ application/vnd.mitsubishi.misty-guard.trustweb application/vnd.ms-artgalry application/vnd.ms-asf -application/vnd.ms-excel +application/vnd.ms-excel xls application/vnd.ms-powerpoint ppt application/vnd.ms-project application/vnd.ms-tnef 1.2 +8 -0 apache-apr/pthreads/src/Apache.dsp Index: Apache.dsp =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Apache.dsp,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- Apache.dsp 1999/01/21 23:08:31 1.1 +++ Apache.dsp 1999/06/10 06:25:40 1.2 @@ -96,6 +96,14 @@ # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\os\win32\apache.ico +# End Source File +# Begin Source File + +SOURCE=.\os\win32\apache.rc +# End Source File # End Group # End Target # End Project 1.2 +81 -21 apache-apr/pthreads/src/Apache.mak Index: Apache.mak =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Apache.mak,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- Apache.mak 1999/01/21 23:08:31 1.1 +++ Apache.mak 1999/06/10 06:25:40 1.2 @@ -25,9 +25,6 @@ NULL=nul !ENDIF -CPP=cl.exe -RSC=rc.exe - !IF "$(CFG)" == "Apache - Win32 Release" OUTDIR=.\ApacheR @@ -47,6 +44,7 @@ !ENDIF CLEAN : + [EMAIL PROTECTED] "$(INTDIR)\apache.res" [EMAIL PROTECTED] "$(INTDIR)\main_win32.obj" [EMAIL PROTECTED] "$(INTDIR)\vc50.idb" [EMAIL PROTECTED] "$(OUTDIR)\Apache.exe" @@ -54,10 +52,44 @@ "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" +CPP=cl.exe CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\ /Fp"$(INTDIR)\Apache.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\ApacheR/ CPP_SBRS=. + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +RSC_PROJ=/l 0x809 /fo"$(INTDIR)\apache.res" /d "NDEBUG" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\Apache.bsc" BSC32_SBRS= \ @@ -68,6 +100,7 @@ /incremental:no /pdb:"$(OUTDIR)\Apache.pdb" /machine:I386\ /out:"$(OUTDIR)\Apache.exe" LINK32_OBJS= \ + "$(INTDIR)\apache.res" \ "$(INTDIR)\main_win32.obj" "$(OUTDIR)\Apache.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -94,6 +127,7 @@ !ENDIF CLEAN : + [EMAIL PROTECTED] "$(INTDIR)\apache.res" [EMAIL PROTECTED] "$(INTDIR)\main_win32.obj" [EMAIL PROTECTED] "$(INTDIR)\vc50.idb" [EMAIL PROTECTED] "$(INTDIR)\vc50.pdb" @@ -104,29 +138,12 @@ "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" +CPP=cl.exe CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\ /Fp"$(INTDIR)\Apache.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c CPP_OBJS=.\ApacheD/ CPP_SBRS=. -BSC32=bscmake.exe -BSC32_FLAGS=/nologo /o"$(OUTDIR)\Apache.bsc" -BSC32_SBRS= \ - -LINK32=link.exe -LINK32_FLAGS=CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ - winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:console\ - /incremental:yes /pdb:"$(OUTDIR)\Apache.pdb" /debug /machine:I386\ - /out:"$(OUTDIR)\Apache.exe" -LINK32_OBJS= \ - "$(INTDIR)\main_win32.obj" -"$(OUTDIR)\Apache.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - .c{$(CPP_OBJS)}.obj:: $(CPP) @<< $(CPP_PROJ) $< @@ -157,13 +174,56 @@ $(CPP_PROJ) $< << +RSC=rc.exe +RSC_PROJ=/l 0x809 /fo"$(INTDIR)\apache.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\Apache.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=CoreD\ApacheCore.lib kernel32.lib user32.lib gdi32.lib\ + winspool.lib comdlg32.lib advapi32.lib shell32.lib /nologo /subsystem:console\ + /incremental:yes /pdb:"$(OUTDIR)\Apache.pdb" /debug /machine:I386\ + /out:"$(OUTDIR)\Apache.exe" +LINK32_OBJS= \ + "$(INTDIR)\apache.res" \ + "$(INTDIR)\main_win32.obj" +"$(OUTDIR)\Apache.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + !IF "$(CFG)" == "Apache - Win32 Release" || "$(CFG)" == "Apache - Win32 Debug" SOURCE=.\os\win32\main_win32.c "$(INTDIR)\main_win32.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) + +SOURCE=.\os\win32\apache.rc +DEP_RSC_APACH=\ + ".\os\win32\apache.ico"\ + + +!IF "$(CFG)" == "Apache - Win32 Release" + + +"$(INTDIR)\apache.res" : $(SOURCE) $(DEP_RSC_APACH) "$(INTDIR)" + $(RSC) /l 0x809 /fo"$(INTDIR)\apache.res" /i "os\win32" /d "NDEBUG" $(SOURCE) + + +!ELSEIF "$(CFG)" == "Apache - Win32 Debug" + + +"$(INTDIR)\apache.res" : $(SOURCE) $(DEP_RSC_APACH) "$(INTDIR)" + $(RSC) /l 0x809 /fo"$(INTDIR)\apache.res" /i "os\win32" /d "_DEBUG" $(SOURCE) + + +!ENDIF !ENDIF 1.8 +405 -3 apache-apr/pthreads/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/CHANGES,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -u -r1.7 -r1.8 --- CHANGES 1999/06/03 23:46:19 1.7 +++ CHANGES 1999/06/10 06:25:40 1.8 @@ -20,8 +20,410 @@ *) Removed the ap_block_alarms and ap_unblock_alarm calls. These aren't needed in a threaded server. -Changes with Apache 1.3.5 +Changes with Apache 1.3.7 + + *) Win32: The query switch "apache -S" didn't exit after showing the + vhost settings. That was inconsistent with the other query functions. + [Bill Stoddard - Fixed by Martin on Unix in 1.3.4] + + *) Win32: Changed behaviour of apache -k restart. + Previously, the server would drain all connections in the stack's + listen queue before honoring the restart. On a busy server, this + could take hours. Now, a restart is honored almost immediately. + All connections in Apache's queues are handled but connections in + the stack's listen queue are discarded. Restart triggered by + MaxRequestPerChild is unchanged. + [Bill Stoddard <[EMAIL PROTECTED]>] + + *) Win32: Eliminated unnecessary call to wait_for_multiple_objects in + the accept loop. Good for a 5% performance boost. Cleaned up + parent/child process management code. + [Bill Stoddard <[EMAIL PROTECTED]>] + + *) Added ceiling on file size for memory mapped files. + [John Giannandrea <[EMAIL PROTECTED]>] PR#4122 + + *) Fix ndbm.h include problems with brain-dead glibc >= 2.1 which + has ndbm.h in a non-standard db1/ subdir. PR#4431, PR#4528 + [Henri Gomez <[EMAIL PROTECTED]>, Ralf S. Engelschall] + + *) Determine AP_BYTE_ORDER for ap_config_auto.h and already + use this at least for Expat. [Ralf S. Engelschall] + + *) Allow .module files to specify libraries with Lib:. + [Ben Laurie] + + *) Allow SetEnvIf[NoCase] to test environment variables as well + as header fields and request attributes. [Ken Coar] + + *) Fix mod_autoindex's handling of ScanHTMLTitles when file + content-types are "text/html;parameters". PR#4524 [Ken Coar] + + *) Remove "mxb" support from mod_negotiation -- it was a draft feature + never accepted into any standard, and it opens up certain DoS + attacks. [Koen Holtman <[EMAIL PROTECTED]>] + + *) The source is now quad (long long) aware as needed. Specifically, + the Configure process determines the correct size of off_t and + *void. When the OS/platform/compiler supports quads, ap_snprintf() + provides for the 'q' format qualifier (if quads are not available, + 'q' is silently "demoted" to long). [Jim Jagielski] + + *) When the username or password fed to htpasswd is too long, include the + size limit in the error message. Also report illegal characters + (currently only ':') in the username. Add the size restrictions + to the man page. [Ken Coar] + + *) Fixed the configure --without-support option so it doesn't result in + an infinite loop. [Marc Slemko] + + *) Piped error logs could cause a segfault if an error occured + during configuration after a restart. + [Aidan Cully <[EMAIL PROTECTED]>] PR#4456 + + *) If a "Location" field was stored in r->err_headers_out rather + than r->headers_out, redirect processing wouldn't find it and + the server would core dump on ap_escape_html(NULL). Check both + tables and raise HTTP_INTERNAL_SERVER_ERROR with a log message + if Location isn't set. [Doug MacEachern, Ken Coar] + + *) Add RULE_EXPAT, the src/lib/ directory structure, and a modified copy + of the Expat 1.0.2 distribution. [Greg Stein] + + *) Replace regexec() calls with calls to a new API stub function + ap_regexec(). This solves problems with DSO modules which use the regex + library. [Jens-Uwe Mager <[EMAIL PROTECTED]>, Ralf S. Engelschall] + + *) Add 'Request_Protocol' special keyword to mod_setenvif so that + environment variables can be set according to the protocol version + (e.g., HTTP/0.9 or HTTP/1.1) of the request. [Ken Coar] + + *) Add DSO support for OpenStep (Mach 4.2) platform. + [Ralf S. Engelschall, Rex Dieter <[EMAIL PROTECTED]>] PR#3997 + + *) Fix sed regex for generating ap_config_auto.h in src/Configure. + [Jan Gallo <[EMAIL PROTECTED]>] PR#3690, PR#4373 + + *) Switch to /bin/sh5 in APACI on Ultrix and friends to avoid problems with + their brain-dead /bin/sh. [Ralf S. Engelschall] PR#4372 + + *) Better DSO flags recognition on NetBSD platforms using ELF. + [Todd Vierling <[EMAIL PROTECTED]>] PR#4310 + + *) Always log months in english format for %t in mod_log_config. + [Petr Lampa <[EMAIL PROTECTED]>] PR#4366, 679 + + *) Support for server-parsed and multiview-determined ReadmeName and + HeaderName files in mod_autoindex. Removed the restriction on + "/"s in ReadmeName and HeaderName directives since the *sub_req* + routines will deal with the access issues. (It's now possible to + have {site|group|project|customer|...} wide readmes and headers.) + [Raymond S Brand <[EMAIL PROTECTED]>, Ken Coar] PR#1574, 3026, 3529, + 3569, 4256 + + *) When stat() fails, don't assume anything about the contents of + the struct stat. [Ed Korthof <[EMAIL PROTECTED]>] + + *) It's OK for a semop to return EINTR, just loop around and try + again. [Dean Gaudet] + + *) Fix configuration engine re-entrant hangups, which solve a + handful of problems seen with mod_perl <Perl> configuration sections + [Salvador Ortiz Garcia <[EMAIL PROTECTED]>] + + *) Mac OS and Mac OS X Server now use the appropriate custom layout + by default when building with APACI; allow for platform-specific + variable defaults in configure. [Wilfredo Sanchez] + + *) Do setgid() before initgroups() in http_main; some platforms + zap the grouplist when setgid() is called. This was fixed in + suexec earlier, but the main httpd code missed the change. + [Rob Saccoccio <[EMAIL PROTECTED]>] PR#2579 + + *) Add recognition of .tgz as a gzipped tarchive. + [Bertrand de Singly <[EMAIL PROTECTED]>] PR#2364 + + *) mod_include's fsize/flastmod should allow only relative paths, just + like "include file". [Jaroslav Benkovsky <[EMAIL PROTECTED]>] + + *) OS/2: Add support for building loadable modules using DLLs. + [Brian Havard] + + *) Add iconsdir, htdocsdir, and cgidir to config.layout. + [Wilfredo Sanchez] + + *) Fix minor but annoying bug with the test for Configuration.tmpl + being newer than Configuration so that it is less likely to fail + when using APACI and shadow sources. [Wilfredo Sanchez] + + *) PORT: Add initial support for Mac OS (versions 10.0 and + greater). Use Mac OS X Server layout for now. Clean up dyld code + in unix/os.c, and don't install the dyld error handlers, which + are no longer needed in Mac OS. [Wilfredo Sanchez] + + *) Rename Rhapsody layout to "Mac OS X Server". Change install + locations to appropriate ones for user-built (as opposed to + system) installs. [Wilfredo Sanchez] + + *) Modify mod_autoindex's handling of AddDescription so that the + behaviour matches the documentation. [Ken Coar] PR#1898, 3072. + + *) Add functionality to the install-bindist.sh script created by + binbuild.sh to use tar when copying distribution files to the + serverroot. This allows upgrading an existing installation + without nesting the new distribution in the old. + + install-bindist.sh now detects the local perl5 path to install + apxs and dbmmanage with proper path to perl interpreter. + + Add an install-binsupport target which copies the source files + for apxs and dbmmanage to bindist to allow these scripts to + be properly installed relative to the destination serverroot. + [Randy Terbush, Covalent Technologies, [EMAIL PROTECTED] + + *) Fix intermittent SEGV in ap_proxy_cache_error() in + src/modules/proxy_util.c where a NULL filepointer and + temporary filename were closed and unlinked. + [Graham Leggett <[EMAIL PROTECTED]>, + Tim Costello <[EMAIL PROTECTED]>] PR#3178 + + *) Fix inconsistant error messages reported by mod_proxy. + [Graham Leggett <[EMAIL PROTECTED]>] + + *) OS/2: Fix terminating CGIs that aren't compiled by EMX GCC when a + connection is aborted. [Brian Havard] + + *) Force the LANG envariable to the known state of "C" so that we + have assurance about how string manipulators (e.g., tr) will + function. [Ken Coar] PR#1630 + + *) Add a directive to allow customising of the tracking cookie name. + [Ken Coar] PR#2921, 4303 + + *) Add "force-no-vary" envariable to allow servers to work around + clients that choke on "Vary" fields in the response header. + [Ken Coar, Dmitry Khrustalev <[EMAIL PROTECTED]>] PR#4118 + + *) Fixed a bug in mod_dir that causes a child process will infinitely + recurse when it attemps to handle a request for a directory wnd the + value of the DirectoryIndex directive is a single dot. Also likely + to happen for anyother values of DirectoryIndex that will map back + to the same directory. The handler now only considers regular files + as being index candidates. No PR#s found. + [Raymond S Brand <[EMAIL PROTECTED]>] + + *) Ease configuration debugging by making TestCompile fall back to + using "make" if the $MAKE variable is unset [Martin Kraemer] + + *) Fixed the ServerSignature directive to work as documented. + [Raymond S Brand <[EMAIL PROTECTED]>] PR#4248 + + *) Add "opt" (SysV-style) layout to config.layout. [Raymond S Brand + <[EMAIL PROTECTED]>] + + *) Add APACI --without-execstrip option which can be used to disable the + stripping of executables on installation. This is very important for DSO + and debugging situations. [Ralf S. Engelschall] + + *) Add support for OS/2 (case insenstive filesystem, .exe suffix, etc) + to APACI files and related scripts. + [Yitzchak Scott-Thoennes <[EMAIL PROTECTED]>, Ralf S. Engelschall] PR#4269 + + *) Add support for standalone mode in TPF + [Joe Moenich <[EMAIL PROTECTED]>] + + *) Fix number of bytes copied by read_connection() in src/support/ab.c + [Jim Cox <[EMAIL PROTECTED]>] PR#4271 + + *) Fix special RewriteCond "-s" pattern matching. + [Bob Finch <[EMAIL PROTECTED]>] + + *) Fix value quoting in src/Configure script for ap_config_auto.h + [Paul Sutton <[EMAIL PROTECTED]>] + + *) Make sure RewriteLock can be used only in the global context, (i.e. + outside of any <VirtualHost> sections) because it's a global facility of + the rewrite engine. [Ralf S. Engelschall] + + *) Fix the ownership delegation for proxy directory under `make install'. + [Ralf S. Engelschall] + + *) APACI would not correctly build suexec. [Maria Verina + <[EMAIL PROTECTED]>] PR#4260 + + *) mod_mime_magic passed only the first 4k of a file to + uncompress/gzip, but those tools sometimes do not produce + any output unless a sufficient portion of the compressed + file is input. Change to pass the entire file -- but + only read 4k of output. + [Marcin Cieslak <[EMAIL PROTECTED]>] PR#4097 + + *) "IndexOptions None" generated extra spaces at the end of each + line. [EMAIL PROTECTED] PR#3770 + + *) The "100 Continue" response wasn't being sent after internal + redirects. [Jose KAHAN <[EMAIL PROTECTED]>] PR#3910, 3806, 3575 + + *) When padding the name with spaces for display, mod_autoindex would + count &, <, and > in their escaped width, messing up the display. + [Dean Gaudet] PR#4075, 3758 + + *) PORT: fixed a compilation problem on NEXT. + [Jacques Distler <[EMAIL PROTECTED]>] PR#4130 + + *) r->request_time wasn't being set properly in certain error conditions. + [Dean Gaudet] PR#4156 + + *) PORT: deal with UTS compiler error in http_protocol.c + [Dave Dykstra <[EMAIL PROTECTED]>] PR#4189 + + *) Add ap_vrprintf() function. [John Tobey <[EMAIL PROTECTED]>] PR#4246 + + *) Fix the mod_mime hash table to work properly with locales other + than C. [Dean Gaudet] PR#3427 + + *) Fix a memory leak which is exacerbated by certain configurations. + [Dean Gaudet] PR#4225 + + *) Prevent clobbering saved IFS values in APACI. [Jim Jagielski] + + *) Fix buffer overflows in ap_uuencode and ap_uudecode pointed out + by "Peter 'Luna' Altberg <[EMAIL PROTECTED]>" and PR#3422 + [Peter 'Luna' Altberg <[EMAIL PROTECTED]>, Ronald Tschalär] + + *) Make {Set,Unset,Pass}Env per-directory instead of per-server. + [Ben Laurie] + + *) Correct an apparent typo: on the Windows and MPE platforms, the + htpasswd utility was limiting passwords to only 8 characters. + [Ken Coar] + + *) EBCDIC platforms: David submitted patches for two bugs in the + MD5 digest port for EBCDIC machines: + a) the htdigest utility overwrote the old contents of the digest file + b) the Content-MD5 header value (ContentDigest directive) was wrong + when the returned file was not converted from EBCDIC, but was a + binary (e.g., image file) in the first place. + [David McCreedy <[EMAIL PROTECTED]>] + + *) support/htpasswd now permits the password to be specified on the + command line with the '-b' switch. This is useful when passwords + need to be maintained by scripts -- particularly in the Win32 + environment. [Ken Coar] + + *) Win32: Win32 multiple services patch. Added capability to install and + run multiple copies of apache as individual services. + + Example 1: + apache -n apache1 -i -f c:/httpd.conf + Installs apache as service 'apache1' and associates c:/httpd.conf + with that service. + net start apache1 + Starts apache1 service. + net stop apache1 + Stops apache1 service + + Example 2: + apache -n apache2 -i + Installs apache as service 'apache2'. httpd.conf is located under + the default server root (/apache/conf/httpd.conf). + net start apache2 + Starts apache2 service. + + Example 3: + apache -n apache3 -i -d c:/program files/apache + Install apache as service 'apache3' and sets server root to + c:/program files/apache. + + Example 4: + apache -n apache2 -k restart + Restart apache2 service + + [Keith Wannamaker, Ken Parzygnat, Bill Stoddard] + + *) Correct the signed/unsigned character handling for the MD5 routines; + mismatches were causing compilation problems with gcc -pedantic and + in the TPF cross-compilation. [Ken Coar] + + *) OS/2: Rework CGI handling to use spawn*() instead of fork/exec, achieving + a roughly 5 fold speed up. [Brian Havard] + + *) proxy ftp: instead of using the hardwired string "text/plain" as + a fallback type for files served by the ftp proxy, use the + ap_default_type() function to determine the configured type. + This allows for special configurations like + <Directory proxy:ftp://some.host> + DefaultType gargle/blurb + </Directory> + Additionally, add the Content-Encoding: header to FTP proxy replies + when the encoding is defined (by the AddEncoding directive). + Because it was missing, it was almost impossible to browse compressed + files using the FTP proxy (works now perfectly in Communicator). + The ftp proxy now also returns the Date: and Server: header lines (if not + much else... This code is "somewhat" broken) like normal requests do. + [Martin Kraemer] + + *) Be more smart in APACI's configure script when determining the UID/GID + for User/Group directives and use the determined UID/GID to initialize + the permissions on the proxycachedir. + [Dirk-Willem van Gulik, Ralf S. Engelschall] + + *) Changed the forking-prior-to-cleanup in the proxy module to first + check wether it actually needs to collect garbage. This reduces + the number of fork()s from one/request to just the odd one an hour. + [Dirk-Willem van Gulik] + + *) Added proxy, auth and header support to src/support/ab.c. Added a + README file to src/support/ + [Dirk-Willem van Gulik] + *) Don't hard-code the path to AWK in --shadow bootstrapping Makefile. + [Ralf S. Engelschall] PR#4050 + + *) Add support for DSO module compilation on BSD/OS 3.x. + [Randy Terbush, Covalent Technologies] + + *) Fix sed-substitutions in `make install': path elements like `httpd/conf' + (for instance from an APACI configure --sysconfdir=/etc/httpd/conf + option) were substituted with $(TARGET).conf, etc. Same for other strings + with dots where the dot wasn't matched as plain text. + [Ralf S. Engelschall] + + *) PORT: Add support for FreeBSD 4.x [Ralf S. Engelschall] + + *) Fix verbose output of APACI configure (option -v) + [Martin Kraemer, Ralf S. Engelschall] + +Changes with Apache 1.3.6 + + *) Removed new PassAllEnv code due to DSO problems. [Lars Eilebrecht] + +Changes with Apache 1.3.5 [not released] + + *) M_INVALID needed a value within the scope of METHODS so that unknown + methods can be access controlled. [Roy Fielding] PR#3821 + + *) Added PassAllEnv; makes server's entire environment available + to CGIs and SSIs executed within directive's scope. [Ken Coar] + + *) ap_uuencode() always added two trailing '='s and encoding of + 8 bit characters on a machine with signed char may produced + incorrect results. Additionally ap_uuencode() should now + work correctly on EBCDIC platforms. + [Ronald Tschalär <[EMAIL PROTECTED]>] PR#3411 + + *) WIN32: Binary installer now runs the configuration DLL before + the reboot prompt (which is only given if MSVCRT.DLL system + DLL is new or updated). This should avoid the configuration + directory being empty after installation. [Paul Sutton] + PR#3767, 3800, 3827, 3850, 3900, 3953, 3988 + + *) WIN32: Binary installer now creates Start menu options to start + and stop Apache as a console application and to uninstall + the Apache service on NT. [Paul Sutton] PR#3741 + + *) WIN32: Apache.exe now contains an icon. [Paul Sutton] + *) PORT: Switch back to using fcntl() locking on Linux -- instabilities have been reported with flock() locking (probably related to kernel version). [Dean Gaudet] PR#2723, 3531 @@ -40,7 +442,7 @@ *) ap_isxdigit was somehow neglected when adding the ap_isfoo() macros for 8-bit safeness. [Dean Gaudet] - *) Use -fPIC instead of -fpic on Solaris and SunOS for compiling DSOs + *) PORT: Use -fPIC instead of -fpic on Solaris and SunOS for compiling DSOs because SPARCs have a small machine-specific maximum size for the Global Offset Table which is often exceeded when compiling one of the larger third-party modules with Apache. [Peter Urban <[EMAIL PROTECTED]>] PR#3977 @@ -148,7 +550,7 @@ server error" it does currently. The general exposure mechanism can be triggered by any module by setting the "verbose-error-to" note to "*"; this allows more than just proxy errors to be exposed. - [Cliff Skolnick, Roy Fielding, Martin Kraemer] Related to PR#3455 + [Cliff Skolnick, Roy Fielding, Martin Kraemer] Related to PR#3455, 4086 *) Moved man pages for ab and apachectrl to section 8. [Wilfredo Sanchez, Roy Fielding] 1.3 +7 -0 apache-apr/pthreads/src/Configuration.tmpl Index: Configuration.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Configuration.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- Configuration.tmpl 1999/02/07 06:29:09 1.2 +++ Configuration.tmpl 1999/06/10 06:25:41 1.3 @@ -160,12 +160,19 @@ # is performing this function. If PARANOID is set to yes, it will # actually print-out the code that the modules execute # +# EXPAT: +# Include James Clark's Expat package into Apache, for use by the +# modules. The "default" is to include it if the lib/expat-lite/ +# directory is present. This rule will always be interpreted as "no" +# if the directory is not present. +# Rule SOCKS4=no Rule SOCKS5=no Rule IRIXNIS=no Rule IRIXN32=yes Rule PARANOID=no +Rule EXPAT=default # The following rules should be set automatically by Configure. However, if # they are not set by Configure (because we don't know the correct value for 1.10 +220 -31 apache-apr/pthreads/src/Configure Index: Configure =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Configure,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -u -r1.9 -r1.10 --- Configure 1999/04/20 05:29:41 1.9 +++ Configure 1999/06/10 06:25:41 1.10 @@ -64,6 +64,7 @@ # fp2rp: # slo.sh: +LANG=C; export LANG exitcode=0 trap 'rm -f $tmpfile $tmpfile2 $tmpfile3 $tmpconfig $awkfile; exit $exitcode' 0 1 2 3 15 @@ -76,7 +77,8 @@ tmpfile3=$tmpfile.3 awkfile=$tmpfile.4 tmpconfig=$tmpfile.5 -SUBDIRS="ap main modules" +SUBDIRS="ap main" +APLIBDIRS="" #################################################################### ## Now handle any arguments, which, for now, is -file @@ -108,7 +110,7 @@ ## Now see if Configuration.tmpl is more recent than $file. If ## so, then we complain and bail out ## -if ls -lt Configuration.tmpl $file | head -1 | \ +if ls -lt $file Configuration.tmpl | head -1 | \ grep 'Configuration.tmpl' > /dev/null then echo "Configuration.tmpl is more recent than $file;" @@ -222,6 +224,7 @@ RULE_IRIXNIS=`./helpers/CutRule IRIXNIS $file` RULE_IRIXN32=`./helpers/CutRule IRIXN32 $file` RULE_PARANOID=`./helpers/CutRule PARANOID $file` +RULE_EXPAT=`./helpers/CutRule EXPAT $file` RULE_SHARED_CORE=`./helpers/CutRule SHARED_CORE $file` RULE_SHARED_CHAIN=`./helpers/CutRule SHARED_CHAIN $file` @@ -323,7 +326,6 @@ LDFLAGS="$LDFLAGS -lm" RULE_SHARED_CORE=no DEF_SHARED_CORE=no - using_shlib=0 ;; *-apollo-*) OS='Apollo Domain' @@ -338,8 +340,8 @@ OSDIR="os/os2" DEF_WANTHSREGEX=yes OS='EMX OS/2' - CFLAGS="$CFLAGS -DOS2 -Zbsd-signals -Zbin-files -DTCPIPV4 -g" - LDFLAGS="$LDFLAGS -Zexe" + CFLAGS="$CFLAGS -DOS2 -Zbsd-signals -Zbin-files -Zcrtdll -DTCPIPV4 -g" + LDFLAGS="$LDFLAGS -Zexe -Zcrtdll" LIBS="$LIBS -lsocket -lufc -lbsd" DBM_LIB="-lgdbm" SHELL=sh @@ -444,6 +446,11 @@ DBM_LIB="" DB_LIB="" ;; + *-bsdi3) + if [ "x$using_shlib" = "x1" ] ; then + CC="shlicc2" + fi + ;; *-bsdi*) OS='BSDI' DBM_LIB="" @@ -461,7 +468,7 @@ PLATOSVERS=`echo $PLAT | sed 's/^.*freebsd//'` OS="FreeBSD $PLATOSVERS" case "$PLATOSVERS" in - [23]*) + [234]*) DEF_WANTHSREGEX=no CFLAGS="$CFLAGS -funsigned-char" ;; @@ -485,16 +492,18 @@ CC='cc' OPTIM='-O' CFLAGS="$CFLAGS -DNEXT" - CFLAGS_SHLIB='-dynamic -fno-common' - LD_SHLIB='cc' - LDFLAGS_SHLIB='-dynamiclib -undefined warning' DEF_WANTHSREGEX=yes ;; *-apple-rhapsody*) OS='Mac OS X Server' - CFLAGS="$CFLAGS -DRHAPSODY" + CFLAGS="$CFLAGS -DMAC_OS_X_SERVER" DEF_WANTHSREGEX=yes ;; + *-apple-macos*) + OS='Mac OS' + CFLAGS="$CFLAGS -DMAC_OS" + DEF_WANTHSREGEX=yes + ;; *-dec-osf*) OS='DEC OSF/1' CFLAGS="$CFLAGS -DOSF1" @@ -944,6 +953,8 @@ SHLIB_SUFFIX_NAME=so SHLIB_SUFFIX_DEPTH=all SHLIB_EXPORT_FILES=no + SHARED_CORE_EP='lib$(TARGET).ep' + SHCORE_IMPLIB='' case "$PLAT" in *-linux1) CFLAGS_SHLIB="-fpic" @@ -962,7 +973,7 @@ LDFLAGS_SHLIB_EXPORT="" SHLIB_SUFFIX_DEPTH=2 ;; - *-freebsd3*) + *-freebsd3*|*-freebsd4*) CFLAGS_SHLIB="-fpic" LDFLAGS_SHLIB="-Bshareable" OBJFORMAT=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` @@ -980,24 +991,34 @@ LDFLAGS_SHLIB_EXPORT="" SHLIB_SUFFIX_DEPTH=2 ;; - alpha-*-netbsd*|mips-*-netbsd*|powerpc-*-netbsd*) - CFLAGS_SHLIB="-fpic -DPIC" - LDFLAGS_SHLIB="-shared" - LDFLAGS_SHLIB_EXPORT="" - SHLIB_SUFFIX_DEPTH=2 - ;; *-netbsd*) - CFLAGS_SHLIB="-fpic -DPIC" - LDFLAGS_SHLIB="-Bshareable" - LDFLAGS_SHLIB_EXPORT="" + CFLAGS_SHLIB="-fPIC -DPIC" + if echo __ELF__ | ${CC} -E - | grep -q __ELF__; then + LDFLAGS_SHLIB="-Bshareable" + LDFLAGS_SHLIB_EXPORT="" + else + LDFLAGS_SHLIB="-shared" + LDFLAGS_SHLIB_EXPORT="-Wl,-E" + fi SHLIB_SUFFIX_DEPTH=2 ;; + *-bsdi3) + LD_SHLIB="shlicc2" + LDFLAGS_SHLIB="-r" + ;; *-bsdi) CFLAGS_SHLIB="-fPIC" LDFLAGS_SHLIB="-shared" LDFLAGS_SHLIB_EXPORT="-rdynamic" ;; - *-apple-rhapsody*) + *-next-openstep*) + LD_SHLIB='cc' + CFLAGS_SHLIB='-dynamic -fno-common' + LDFLAGS_SHLIB='-bundle -undefined warning' + LDFLAGS_SHLIB_EXPORT='' + SHLIB_SUFFIX_DEPTH=0 + ;; + *-apple-rhapsody* | *-apple-macos* ) LD_SHLIB="cc" CFLAGS_SHLIB="" LDFLAGS_SHLIB='$(EXTRA_LDFLAGS) -bundle -undefined suppress' @@ -1162,6 +1183,19 @@ LDFLAGS_SHLIB_EXPORT="-Zlink=dynamic -Wl,-Bexport" CFLAGS_SHLIB='-Zpic' ;; + *-OS/2*) + DEF_SHARED_CORE=yes + LDFLAGS_SHLIB="`echo $LDFLAGS|sed -e s/-Zexe//` -Zdll" + SHLIB_SUFFIX_NAME=dll + SHLIB_SUFFIX_DEPTH=0 + LD_SHLIB=$CC + LD_SHCORE_DEF="ApacheCoreOS2.def" + LD_SHCORE_LIBS="$LIBS" + LIBS_SHLIB='$(SRCDIR)/ApacheCoreOS2.a -lsocket -lbsd $(EXTRA_LIBS)' + SHARED_CORE_EP='' + SHCORE_IMPLIB='ApacheCoreOS2.a' + OS_MODULE_INCLUDE='Makefile.OS2' + ;; *) ## ok, no known explict support for shared objects ## on this platform, but we give not up immediately. @@ -1510,8 +1544,13 @@ fi . ./$tmpfile3 fi + if grep "Libs:" $tmpfile2 > /dev/null; then + modlibs1=`grep Libs: $tmpfile2 | sed 's/^.*Libs:[ ]*//'` + echo " o $modbase adds libraries: $modlibs1" + modlibs="$modlibs $modlibs1" + fi rm -f $tmpfile2 $tmpfile3 - if [ "x$ext" != "xso" ]; then + if [ "x$ext" != "x$SHLIB_SUFFIX_NAME" ]; then ext=o fi fi @@ -1519,11 +1558,11 @@ modname=`echo $modbase | sed 's/^.*\///' | \ sed 's/^mod_//' | sed 's/^lib//' | sed 's/$/_module/'` fi - if [ "x$ext" != "xso" ]; then + if [ "x$ext" != "x$SHLIB_SUFFIX_NAME" ]; then echo "Module $modname $modbase.$ext" >>$tmpfile fi # optionally generate export file for some linkers - if [ "x$ext" = "xso" -a "x$SHLIB_EXPORT_FILES" = "xyes" ]; then + if [ "x$ext" = "x$SHLIB_SUFFIX_NAME" -a "x$SHLIB_EXPORT_FILES" = "xyes" ]; then echo "$modname" >$modbase.exp fi done @@ -1540,9 +1579,29 @@ fi #################################################################### +## Add in the Expat library if needed/wanted. +## +if [ -d ./lib/expat-lite/ ]; then + if [ "x$RULE_EXPAT" = "xdefault" ]; then + RULE_EXPAT=yes + fi +else + if [ "$xRULE_EXPAT" = "xyes" ]; then + echo "ERROR: RULE_EXPAT set to \"yes\" but is not available." + exit 1 + else + RULE_EXPAT=no + fi +fi +if [ "x$RULE_EXPAT" = "xyes" ]; then + EXPATLIB="lib/expat-lite/libexpat.a" + APLIBDIRS="expat-lite $APLIBDIRS" + CFLAGS="$CFLAGS -DUSE_EXPAT -I\$(SRCDIR)/lib/expat-lite" +fi + +#################################################################### ## Now the SHARED_CHAIN stuff ## -LIBS_SHLIB='' if [ "x$using_shlib" = "x1" ] ; then if [ "x$RULE_SHARED_CHAIN" = "xdefault" ] ; then RULE_SHARED_CHAIN=$DEF_SHARED_CHAIN @@ -1575,7 +1634,7 @@ # select the special subtarget for shared core generation SUBTARGET=target_shared # determine additional suffixes for libhttpd.so - V=1 R=3 P=5 + V=1 R=3 P=7 if [ "x$SHLIB_SUFFIX_DEPTH" = "x0" ]; then SHLIB_SUFFIX_LIST="" fi @@ -1611,6 +1670,10 @@ if [ "x$TLDFLAGS_SHLIB_EXPORT" = "x" ]; then echo "LDFLAGS_SHLIB_EXPORT=$LDFLAGS_SHLIB_EXPORT" >> Makefile.config fi + echo "LD_SHCORE_DEF=$LD_SHCORE_DEF" >> Makefile.config + echo "LD_SHCORE_LIBS=$LD_SHCORE_LIBS" >> Makefile.config + echo "SHARED_CORE_EP=$SHARED_CORE_EP" >> Makefile.config + echo "SHCORE_IMPLIB=$SHCORE_IMPLIB" >> Makefile.config fi #################################################################### @@ -1751,7 +1814,7 @@ #################################################################### ## Now add the target for the main Makefile ## -echo "SUBDIRS=$SUBDIRS" >> Makefile +echo "SUBDIRS=$SUBDIRS lib modules" >> Makefile echo "SUBTARGET=$SUBTARGET" >> Makefile echo "SHLIB_SUFFIX_NAME=$SHLIB_SUFFIX_NAME" >> Makefile echo "SHLIB_SUFFIX_LIST=$SHLIB_SUFFIX_LIST" >> Makefile @@ -1779,6 +1842,7 @@ echo "LDFLAGS1=$LDFLAGS" >>Makefile.config echo "MFLAGS_STATIC=$MFLAGS_STATIC" >>Makefile.config echo "REGLIB=$REGLIB" >>Makefile.config +echo "EXPATLIB=$EXPATLIB" >>Makefile.config echo "RANLIB=$RANLIB" >>Makefile.config #################################################################### @@ -1817,6 +1881,93 @@ fi #################################################################### +## More building ap_config_auto.h +## +## We check the sizeof various data types +## +echo " + checking sizeof various data types" +AP_TYPE_QUAD=`./helpers/TestCompile -r sizeof 'long long'` +if [ "x$AP_TYPE_QUAD" = "x" ]; then + AP_TYPE_QUAD="unknown_quad" + AP_LONGEST_LONG="long" +else + AP_LONGEST_LONG="long long" +fi + +echo "" >>$AP_CONFIG_AUTO_H +echo "/* determine: longest possible integer type */" >>$AP_CONFIG_AUTO_H +echo "#ifndef AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H +echo "#define AP_LONGEST_LONG $AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H +echo "#endif" >>$AP_CONFIG_AUTO_H + +#################################################################### +## More building ap_config_auto.h +## +## We check for the endianess of the machine +## +AP_BYTE_ORDER=`./helpers/TestCompile -r byteorder` +if [ "x$AP_BYTE_ORDER" = "x21" ]; then + AP_BYTE_ORDER="21" # big endian +else + AP_BYTE_ORDER="12" # little endian +fi + +echo "" >>$AP_CONFIG_AUTO_H +echo "/* determine: byte order of machine (12: little endian, 21: big endian) */" >>$AP_CONFIG_AUTO_H +echo "#ifndef AP_BYTE_ORDER" >>$AP_CONFIG_AUTO_H +echo "#define AP_BYTE_ORDER $AP_BYTE_ORDER" >>$AP_CONFIG_AUTO_H +echo "#endif" >>$AP_CONFIG_AUTO_H + +## +## Now compare the sizes of off_t to long +## +AP_TYPE_OFF_T=`./helpers/TestCompile -r sizeof off_t` +if [ "x$AP_TYPE_OFF_T" = "x" ]; then + AP_TYPE_OFF_T="unknown_off_t" +fi + +AP_TYPE_LONG=`./helpers/TestCompile -r sizeof long` +if [ "x$AP_TYPE_LONG" = "x" ]; then + AP_TYPE_LONG="unknown_long" +fi + +if [ "x$AP_TYPE_OFF_T" != "x$AP_TYPE_LONG" ]; then + echo "" >>$AP_CONFIG_AUTO_H + echo "/* determine: is off_t a quad */" >>$AP_CONFIG_AUTO_H + echo "#ifndef AP_OFF_T_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#define AP_OFF_T_IS_QUAD 1" >>$AP_CONFIG_AUTO_H + echo "#endif" >>$AP_CONFIG_AUTO_H +else + echo "" >>$AP_CONFIG_AUTO_H + echo "/* determine: is off_t a quad */" >>$AP_CONFIG_AUTO_H + echo "#ifndef AP_OFF_T_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#undef AP_OFF_T_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#endif" >>$AP_CONFIG_AUTO_H +fi + +## +## Now see of void * is as big as a quad (long long) +## +AP_TYPE_VOID_P=`./helpers/TestCompile -r sizeof 'void *'` +if [ "x$AP_TYPE_VOID_P" = "x" ]; then + AP_TYPE_VOID_P="unknown_void_p" +fi + +if [ "x$AP_TYPE_VOID_P" = "x$AP_TYPE_QUAD" ]; then + echo "" >>$AP_CONFIG_AUTO_H + echo "/* determine: is void * a quad */" >>$AP_CONFIG_AUTO_H + echo "#ifndef AP_VOID_P_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#define AP_VOID_P_IS_QUAD 1" >>$AP_CONFIG_AUTO_H + echo "#endif" >>$AP_CONFIG_AUTO_H +else + echo "" >>$AP_CONFIG_AUTO_H + echo "/* determine: is void * a quad */" >>$AP_CONFIG_AUTO_H + echo "#ifndef AP_VOID_P_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#undef AP_VOID_P_IS_QUAD" >>$AP_CONFIG_AUTO_H + echo "#endif" >>$AP_CONFIG_AUTO_H +fi + +#################################################################### ## Finish building ap_config_auto.h ## ## We pick out all -D's from CFLAGS and insert them as defines into @@ -1826,7 +1977,7 @@ TEXTRA_CFLAGS=`egrep '^EXTRA_CFLAGS=' Makefile.config | tail -1 |\ sed -e 's;^EXTRA_CFLAGS=;;' -e 's;\`.*\`;;'` tmpstr=`echo $CFLAGS $TEXTRA_CFLAGS |\ - sed -e 's;[ ]\([+-]\);!\1;g' -e 's/\\\"/\"/g' -e 's/\([^\\]\)"/\1/g'` + sed -e 's;[ ]\([+-]\);!\1;g' -e 's/\([^\\\]\)"/\1/g' -e 's/\\\"/\"/g'` OIFS="$IFS" IFS='!' for cflag in $tmpstr; do @@ -1856,7 +2007,7 @@ #################################################################### ## Finish creating the Makefile.config file ## -echo "LIBS1=$LIBS">> Makefile.config +echo "LIBS1=$modlibs $LIBS">> Makefile.config echo "##" >> Makefile.config echo "## (End of automatically generated section)">> Makefile.config echo "##" >> Makefile.config @@ -1894,7 +2045,7 @@ sed -e "s#@@Configuration@@#$file#" "Makefile.tmpl" >>Makefile # xxx/Makefile -MAKEDIRS="support main ap regex $OSDIR" +MAKEDIRS="support $SUBDIRS" for dir in $MAKEDIRS ; do echo Creating Makefile in $dir ./helpers/mfhead $dir $file > $dir/Makefile @@ -1903,6 +2054,40 @@ done #################################################################### +## Now create the lib/Makefile +## +./helpers/mfhead modules $file > lib/Makefile +$CAT Makefile.config | sed -e 's:^SRCDIR=.*:SRCDIR=..:' >> lib/Makefile + +$CAT << EOF >> lib/Makefile +APLIBS=$APLIBDIRS +CFLAGS=\$(OPTIM) \$(CFLAGS1) \$(EXTRA_CFLAGS) + +default: all + +all clean distclean depend :: + @for i in \$(APLIBS) ""; do \\ + if [ "x\$\$i" != "x" ]; then \\ + echo "===> \$(SDP)lib/\$\$i"; \\ + (cd \$\$i && \$(MAKE) \$(MFLAGS_STATIC) SDP='\$(SDP)' CC='\$(CC)' AUX_CFLAGS='\$(CFLAGS)' RANLIB='\$(RANLIB)' \$@) || exit 1; \\ + echo "<=== \$(SDP)lib/\$\$i"; \\ + fi; \\ + done + +EOF + +#################################################################### +## Now create the lib/xxx/Makefile +## + +for dir in $APLIBDIRS ; do + echo Creating Makefile in lib/$dir + ./helpers/mfhead lib/$dir $file > lib/$dir/Makefile + $CAT Makefile.config lib/$dir/Makefile.tmpl |\ + sed -e "s:^SRCDIR=.*:SRCDIR=`./helpers/fp2rp lib/$dir`:" >> lib/$dir/Makefile +done + +#################################################################### ## Now create the modules/Makefile ## ./helpers/mfhead modules $file > modules/Makefile @@ -1999,7 +2184,7 @@ ar cr $@ $(OBJS) $(RANLIB) $@ -.SUFFIXES: .o .so +.SUFFIXES: .o .so .dll .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< @@ -2025,6 +2210,10 @@ && rm Makefile.new EOF + fi + + if [ "x$OS_MODULE_INCLUDE" != "x" ]; then + echo "include $OS_MODULE_INCLUDE" >> $moddir/Makefile fi $CAT << 'EOF' >> $moddir/Makefile 1.3 +8 -0 apache-apr/pthreads/src/Makefile.nt Index: Makefile.nt =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Makefile.nt,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- Makefile.nt 1999/02/07 06:29:09 1.2 +++ Makefile.nt 1999/06/10 06:25:41 1.3 @@ -57,6 +57,7 @@ cd .. cd support nmake /nologo CFG="htpasswd - Win32 %LONG%" -f htpasswd.mak + nmake /nologo CFG="htdigest - Win32 %LONG%" -f htdigest.mak cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 %LONG%" -f gen_uri_delims.mak @@ -87,6 +88,7 @@ -mkdir $(INSTDIR)\modules -mkdir $(INSTDIR)\logs -mkdir $(INSTDIR)\conf + -mkdir $(INSTDIR)\bin copy Apache%SHORT%\Apache.exe $(INSTDIR) copy Core%SHORT%\ApacheCore.dll $(INSTDIR) copy os\win32\ApacheModuleStatus%SHORT%\ApacheModuleStatus.dll $(INSTDIR)\modules @@ -100,6 +102,8 @@ copy os\win32\ApacheModuleSpeling%SHORT%\ApacheModuleSpeling.dll $(INSTDIR)\modules copy os\win32\ApacheModuleUserTrack%SHORT%\ApacheModuleUserTrack.dll $(INSTDIR)\modules copy modules\proxy\%LONG%\ApacheModuleProxy.dll $(INSTDIR)\modules + copy support\%LONG%\htpasswd.exe $(INSTDIR)\bin + copy support\%LONG%\htdigest.exe $(INSTDIR)\bin _clean: cd os\win32 @@ -110,6 +114,10 @@ cd .. cd ap nmake /nologo CFG="ap - Win32 %LONG%" -f ap.mak clean + cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 %LONG%" -f htpasswd.mak clean + nmake /nologo CFG="htdigest - Win32 %LONG%" -f htdigest.mak clean cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 %LONG%" -f gen_uri_delims.mak clean 1.4 +10 -4 apache-apr/pthreads/src/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Makefile.tmpl,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- Makefile.tmpl 1999/03/17 17:00:36 1.3 +++ Makefile.tmpl 1999/06/10 06:25:42 1.4 @@ -14,6 +14,11 @@ .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< +# Used to generate import library for OS/2 +.SUFFIXES: .def +.def.a: + emximp -o $@ $< + all: @@Configuration@@ $(TARGET) @@Configuration@@: Configuration.tmpl @@ -28,15 +33,15 @@ target_static: subdirs modules.o $(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \ - -o $(TARGET) buildmark.o $(OBJS) $(REGLIB) $(LIBS) + -o $(TARGET) buildmark.o $(OBJS) $(REGLIB) $(EXPATLIB) $(LIBS) target_compile_only: subdirs modules.o $(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c -target_shared: lib$(TARGET).ep +target_shared: $(SHCORE_IMPLIB) $(SHARED_CORE_EP) lib$(TARGET).$(SHLIB_SUFFIX_NAME) $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \ -o $(TARGET) -DSHARED_CORE_BOOTSTRAP main/http_main.c \ - ap/libap.a $(LIBS) + ap/libap.a $(LIBS) $(SHCORE_IMPLIB) lib$(TARGET).ep: lib$(TARGET).$(SHLIB_SUFFIX_NAME) $(CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_SHLIB_EXPORT) \ @@ -45,7 +50,7 @@ lib$(TARGET).$(SHLIB_SUFFIX_NAME): subdirs modules.o $(CC) -c $(INCLUDES) $(CFLAGS) buildmark.c - $(LD_SHLIB) $(LDFLAGS_SHLIB) -o lib$(TARGET).$(SHLIB_SUFFIX_NAME) buildmark.o $(OBJS) $(REGLIB) + $(LD_SHLIB) $(LDFLAGS_SHLIB) -o lib$(TARGET).$(SHLIB_SUFFIX_NAME) buildmark.o $(OBJS) $(REGLIB) $(EXPATLIB) $(LD_SHCORE_DEF) $(LD_SHCORE_LIBS) @if [ ".$(SHLIB_SUFFIX_LIST)" != . ]; then \ rm -f lib$(TARGET).$(SHLIB_SUFFIX_NAME).*; \ for suffix in $(SHLIB_SUFFIX_LIST) ""; do \ @@ -88,6 +93,7 @@ -rm -f modules.c -rm -f modules/Makefile -rm -f regex/Makefile + -rm -f lib/Makefile -rm -f Makefile.config -rm -f Makefile 1.3 +8 -0 apache-apr/pthreads/src/Makefile_win32.txt Index: Makefile_win32.txt =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Makefile_win32.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- Makefile_win32.txt 1999/03/17 17:00:37 1.2 +++ Makefile_win32.txt 1999/06/10 06:25:42 1.3 @@ -35,6 +35,7 @@ cd .. cd support nmake /nologo CFG="htpasswd - Win32 Release" -f htpasswd.mak + nmake /nologo CFG="htdigest - Win32 Release" -f htdigest.mak cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Release" -f gen_uri_delims.mak @@ -65,6 +66,7 @@ -mkdir $(INSTDIR)\modules -mkdir $(INSTDIR)\logs -mkdir $(INSTDIR)\conf + -mkdir $(INSTDIR)\bin copy ApacheR\Apache.exe $(INSTDIR) copy CoreR\ApacheCore.dll $(INSTDIR) copy os\win32\ApacheModuleStatusR\ApacheModuleStatus.dll $(INSTDIR)\modules @@ -78,6 +80,8 @@ copy os\win32\ApacheModuleSpelingR\ApacheModuleSpeling.dll $(INSTDIR)\modules copy os\win32\ApacheModuleUserTrackR\ApacheModuleUserTrack.dll $(INSTDIR)\modules copy modules\proxy\Release\ApacheModuleProxy.dll $(INSTDIR)\modules + copy support\Release\htpasswd.exe $(INSTDIR)\bin + copy support\Release\htdigest.exe $(INSTDIR)\bin clean: cd os\win32 @@ -88,6 +92,10 @@ cd .. cd ap nmake /nologo CFG="ap - Win32 Release" -f ap.mak clean + cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 Release" -f htpasswd.mak clean + nmake /nologo CFG="htdigest - Win32 Release" -f htdigest.mak clean cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Release" -f gen_uri_delims.mak clean 1.3 +8 -0 apache-apr/pthreads/src/Makefile_win32_debug.txt Index: Makefile_win32_debug.txt =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/Makefile_win32_debug.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- Makefile_win32_debug.txt 1999/03/17 17:00:39 1.2 +++ Makefile_win32_debug.txt 1999/06/10 06:25:42 1.3 @@ -35,6 +35,7 @@ cd .. cd support nmake /nologo CFG="htpasswd - Win32 Debug" -f htpasswd.mak + nmake /nologo CFG="htdigest - Win32 Debug" -f htdigest.mak cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Debug" -f gen_uri_delims.mak @@ -65,6 +66,7 @@ -mkdir $(INSTDIR)\modules -mkdir $(INSTDIR)\logs -mkdir $(INSTDIR)\conf + -mkdir $(INSTDIR)\bin copy ApacheD\Apache.exe $(INSTDIR) copy CoreD\ApacheCore.dll $(INSTDIR) copy os\win32\ApacheModuleStatusD\ApacheModuleStatus.dll $(INSTDIR)\modules @@ -78,6 +80,8 @@ copy os\win32\ApacheModuleSpelingD\ApacheModuleSpeling.dll $(INSTDIR)\modules copy os\win32\ApacheModuleUserTrackD\ApacheModuleUserTrack.dll $(INSTDIR)\modules copy modules\proxy\Debug\ApacheModuleProxy.dll $(INSTDIR)\modules + copy support\Debug\htpasswd.exe $(INSTDIR)\bin + copy support\Debug\htdigest.exe $(INSTDIR)\bin clean: cd os\win32 @@ -88,6 +92,10 @@ cd .. cd ap nmake /nologo CFG="ap - Win32 Debug" -f ap.mak clean + cd .. + cd support + nmake /nologo CFG="htpasswd - Win32 Debug" -f htpasswd.mak clean + nmake /nologo CFG="htdigest - Win32 Debug" -f htdigest.mak clean cd .. cd main nmake /nologo CFG="gen_uri_delims - Win32 Debug" -f gen_uri_delims.mak clean 1.3 +5 -2 apache-apr/pthreads/src/ap/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/ap/Makefile.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- Makefile.tmpl 1999/02/07 06:29:13 1.2 +++ Makefile.tmpl 1999/06/10 06:25:46 1.3 @@ -5,8 +5,8 @@ LIB=libap.a -OBJS=ap_execve.o ap_cpystrn.o ap_signal.o \ - ap_slack.o ap_snprintf.o ap_fnmatch.o ap_md5c.o +OBJS=ap_cpystrn.o ap_execve.o ap_fnmatch.o ap_getpass.o ap_md5c.o ap_signal.o \ + ap_slack.o ap_snprintf.o .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< @@ -52,6 +52,9 @@ ap_fnmatch.o: ap_fnmatch.c $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(OSDIR)/os-inline.c \ $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/fnmatch.h +ap_getpass.o: ap_getpass.c $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(OSDIR)/os-inline.c \ + $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/ap.h ap_md5c.o: ap_md5c.c $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h $(OSDIR)/os-inline.c \ $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h $(INCDIR)/ap_md5.h \ 1.3 +43 -28 apache-apr/pthreads/src/ap/ap_md5c.c Index: ap_md5c.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/ap/ap_md5c.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- ap_md5c.c 1999/03/05 22:05:11 1.2 +++ ap_md5c.c 1999/06/10 06:25:47 1.3 @@ -181,7 +181,7 @@ /* MD5 initialization. Begins an MD5 operation, writing a new context. */ -API_EXPORT(void) ap_MD5Init(AP_MD5_CTX * context) +API_EXPORT(void) ap_MD5Init(AP_MD5_CTX *context) { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ @@ -195,8 +195,8 @@ operation, processing another message block, and updating the context. */ -API_EXPORT(void) ap_MD5Update(AP_MD5_CTX * context, const unsigned char *input, - unsigned int inputLen) +API_EXPORT(void) ap_MD5Update(AP_MD5_CTX *context, const unsigned char *input, + unsigned int inputLen) { unsigned int i, idx, partLen; @@ -204,8 +204,10 @@ idx = (unsigned int) ((context->count[0] >> 3) & 0x3F); /* Update number of bits */ - if ((context->count[0] += ((UINT4) inputLen << 3)) < ((UINT4) inputLen << 3)) + if ((context->count[0] += ((UINT4) inputLen << 3)) + < ((UINT4) inputLen << 3)) { context->count[1]++; + } context->count[1] += (UINT4) inputLen >> 29; partLen = 64 - idx; @@ -216,13 +218,15 @@ memcpy(&context->buffer[idx], input, partLen); MD5Transform(context->state, context->buffer); - for (i = partLen; i + 63 < inputLen; i += 64) + for (i = partLen; i + 63 < inputLen; i += 64) { MD5Transform(context->state, &input[i]); + } idx = 0; } - else + else { i = 0; + } /* Buffer remaining input */ memcpy(&context->buffer[idx], &input[i], inputLen - i); @@ -239,8 +243,9 @@ idx = 0; } - else + else { i = 0; + } /* Buffer remaining input */ ebcdic2ascii_strictly(&context->buffer[idx], &input[i], inputLen - i); @@ -250,7 +255,7 @@ /* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ -API_EXPORT(void) ap_MD5Final(unsigned char digest[16], AP_MD5_CTX * context) +API_EXPORT(void) ap_MD5Final(unsigned char digest[16], AP_MD5_CTX *context) { unsigned char bits[8]; unsigned int idx, padLen; @@ -277,10 +282,10 @@ /* Pad out to 56 mod 64. */ idx = (unsigned int) ((context->count[0] >> 3) & 0x3f); padLen = (idx < 56) ? (56 - idx) : (120 - idx); - ap_MD5Update(context, PADDING, padLen); + ap_MD5Update(context, (const unsigned char *)PADDING, padLen); /* Append length (before padding) */ - ap_MD5Update(context, bits, 8); + ap_MD5Update(context, (const unsigned char *)bits, 8); /* Store state in digest */ Encode(digest, context->state, 16); @@ -429,7 +434,8 @@ } } -API_EXPORT(void) ap_MD5Encode(const char *pw, const char *salt, +API_EXPORT(void) ap_MD5Encode(const unsigned char *pw, + const unsigned char *salt, char *result, size_t nbytes) { /* @@ -439,9 +445,12 @@ */ char passwd[120], *p; - const char *sp, *ep; + const unsigned char *sp, *ep; unsigned char final[16]; - int sl, pl, i; + int i; + unsigned int sl; + int pl; + unsigned int pwlen; AP_MD5_CTX ctx, ctx1; unsigned long l; @@ -455,7 +464,7 @@ /* * If it starts with the magic string, then skip that. */ - if (!strncmp(sp, apr1_id, strlen(apr1_id))) { + if (!strncmp((char *)sp, apr1_id, strlen(apr1_id))) { sp += strlen(apr1_id); } @@ -476,15 +485,16 @@ */ ap_MD5Init(&ctx); + pwlen = strlen((char *)pw); /* * The password first, since that is what is most unknown */ - ap_MD5Update(&ctx, pw, strlen(pw)); + ap_MD5Update(&ctx, pw, pwlen); /* * Then our magic string */ - ap_MD5Update(&ctx, apr1_id, strlen(apr1_id)); + ap_MD5Update(&ctx, (const unsigned char *)apr1_id, strlen(apr1_id)); /* * Then the raw salt @@ -495,12 +505,12 @@ * Then just as many characters of the MD5(pw, salt, pw) */ ap_MD5Init(&ctx1); - ap_MD5Update(&ctx1, pw, strlen(pw)); + ap_MD5Update(&ctx1, pw, pwlen); ap_MD5Update(&ctx1, sp, sl); - ap_MD5Update(&ctx1, pw, strlen(pw)); + ap_MD5Update(&ctx1, pw, pwlen); ap_MD5Final(final, &ctx1); - for(pl = strlen(pw); pl > 0; pl -= 16) { - ap_MD5Update(&ctx, final, (pl > 16) ? 16 : pl); + for(pl = pwlen; pl > 0; pl -= 16) { + ap_MD5Update(&ctx, final, (pl > 16) ? 16 : (unsigned int) pl); } /* @@ -511,7 +521,7 @@ /* * Then something really weird... */ - for (i = strlen(pw); i != 0; i >>= 1) { + for (i = pwlen; i != 0; i >>= 1) { if (i & 1) { ap_MD5Update(&ctx, final, 1); } @@ -525,7 +535,7 @@ * can use the string routines without bounds checking. */ strcpy(passwd, apr1_id); - strncat(passwd, sp, sl); + strncat(passwd, (char *)sp, sl); strcat(passwd, "$"); ap_MD5Final(final, &ctx); @@ -538,7 +548,7 @@ for (i = 0; i < 1000; i++) { ap_MD5Init(&ctx1); if (i & 1) { - ap_MD5Update(&ctx1, pw, strlen(pw)); + ap_MD5Update(&ctx1, pw, pwlen); } else { ap_MD5Update(&ctx1, final, 16); @@ -548,14 +558,14 @@ } if (i % 7) { - ap_MD5Update(&ctx1, pw, strlen(pw)); + ap_MD5Update(&ctx1, pw, pwlen); } if (i & 1) { ap_MD5Update(&ctx1, final, 16); } else { - ap_MD5Update(&ctx1, pw, strlen(pw)); + ap_MD5Update(&ctx1, pw, pwlen); } ap_MD5Final(final,&ctx1); } @@ -594,14 +604,19 @@ /* * The hash was created using our custom algorithm. */ - ap_MD5Encode(passwd, hash, sample, sizeof(sample)); + ap_MD5Encode((const unsigned char *)passwd, + (const unsigned char *)hash, sample, sizeof(sample)); } else { /* * It's not our algorithm, so feed it to crypt() if possible. */ -#ifdef WIN32 - return "crypt() unavailable on Win32, cannot validate password"; +#if defined(WIN32) || defined(TPF) + /* + * On Windows, the only alternative to our MD5 algorithm is plain + * text. + */ + ap_cpystrn(sample, passwd, sizeof(sample) - 1); #else crypt_pw = crypt(passwd, hash); ap_cpystrn(sample, crypt_pw, sizeof(sample) - 1); 1.3 +189 -35 apache-apr/pthreads/src/ap/ap_snprintf.c Index: ap_snprintf.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/ap/ap_snprintf.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- ap_snprintf.c 1999/02/07 06:29:14 1.2 +++ ap_snprintf.c 1999/06/10 06:25:48 1.3 @@ -78,12 +78,18 @@ #ifndef TRUE #define TRUE 1 #endif +#ifndef AP_LONGEST_LONG +#define AP_LONGEST_LONG long +#endif #define NUL '\0' #define INT_NULL ((int *)0) #define WIDE_INT long +#define WIDEST_INT AP_LONGEST_LONG typedef WIDE_INT wide_int; typedef unsigned WIDE_INT u_wide_int; +typedef WIDEST_INT widest_int; +typedef unsigned WIDEST_INT u_widest_int; typedef int bool_int; #define S_NULL "(null)" @@ -338,6 +344,10 @@ * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) + * + * Note: we have 2 versions. One is used when we need to use quads + * (conv_10_quad), the other when we don't (conv_10). We're assuming the + * latter is faster. */ static char *conv_10(register wide_int num, register bool_int is_unsigned, register bool_int *is_negative, char *buf_end, @@ -386,6 +396,61 @@ return (p); } +static char *conv_10_quad(register widest_int num, register bool_int is_unsigned, + register bool_int *is_negative, char *buf_end, + register int *len) +{ + register char *p = buf_end; + register u_widest_int magnitude; + + /* + * If the value is less than the maximum unsigned long value, + * then we know we aren't using quads, so use the faster function + */ + if (num <= ULONG_MAX) + return(conv_10( (wide_int)num, is_unsigned, is_negative, + buf_end, len)); + + if (is_unsigned) { + magnitude = (u_widest_int) num; + *is_negative = FALSE; + } + else { + *is_negative = (num < 0); + + /* + * On a 2's complement machine, negating the most negative integer + * results in a number that cannot be represented as a signed integer. + * Here is what we do to obtain the number's magnitude: + * a. add 1 to the number + * b. negate it (becomes positive) + * c. convert it to unsigned + * d. add 1 + */ + if (*is_negative) { + widest_int t = num + 1; + + magnitude = ((u_widest_int) -t) + 1; + } + else + magnitude = (u_widest_int) num; + } + + /* + * We use a do-while loop so that we write at least 1 digit + */ + do { + register u_widest_int new_magnitude = magnitude / 10; + + *--p = (char) (magnitude - new_magnitude * 10 + '0'); + magnitude = new_magnitude; + } + while (magnitude); + + *len = buf_end - p; + return (p); +} + static char *conv_in_addr(struct in_addr *ia, char *buf_end, int *len) @@ -525,6 +590,9 @@ * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) + * + * As with conv_10, we have a faster version which is used when + * the number isn't quad size. */ static char *conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register int *len) @@ -545,6 +613,28 @@ return (p); } +static char *conv_p2_quad(register u_widest_int num, register int nbits, + char format, char *buf_end, register int *len) +{ + register int mask = (1 << nbits) - 1; + register char *p = buf_end; + static const char low_digits[] = "0123456789abcdef"; + static const char upper_digits[] = "0123456789ABCDEF"; + register const char *digits = (format == 'X') ? upper_digits : low_digits; + + if (num <= ULONG_MAX) + return(conv_p2( (u_wide_int)num, nbits, format, buf_end, len)); + + do { + *--p = digits[num & mask]; + num >>= nbits; + } + while (num); + + *len = buf_end - p; + return (p); +} + /* * Do format conversion placing the output in buffer @@ -570,16 +660,22 @@ char prefix_char; double fp_num; + widest_int i_quad = (widest_int) 0; + u_widest_int ui_quad; wide_int i_num = (wide_int) 0; u_wide_int ui_num; char num_buf[NUM_BUF_SIZE]; char char_buf[2]; /* for printing %% and %<unknown> */ + enum var_type_enum { + IS_QUAD, IS_LONG, IS_SHORT, IS_INT + }; + enum var_type_enum var_type = IS_INT; + /* * Flag variables */ - boolean_e is_long; boolean_e alternate_form; boolean_e print_sign; boolean_e print_blank; @@ -677,14 +773,20 @@ /* * Modifier check */ - if (*fmt == 'l') { - is_long = YES; + if (*fmt == 'q') { + var_type = IS_QUAD; + fmt++; + } + else if (*fmt == 'l') { + var_type = IS_LONG; fmt++; } + else if (*fmt == 'h') { + var_type = IS_SHORT; + fmt++; + } else { - if (*fmt == 'h') /* "short" backward compatibility */ - ++fmt; - is_long = NO; + var_type = IS_INT; } /* @@ -700,23 +802,41 @@ */ switch (*fmt) { case 'u': - if (is_long) - i_num = va_arg(ap, u_wide_int); - else - i_num = (wide_int) va_arg(ap, unsigned int); - s = conv_10(i_num, 1, &is_negative, + if (var_type == IS_QUAD) { + i_quad = va_arg(ap, u_widest_int); + s = conv_10_quad(i_quad, 1, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + i_num = (wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + i_num = (wide_int) (unsigned short) va_arg(ap, unsigned int); + else + i_num = (wide_int) va_arg(ap, unsigned int); + s = conv_10(i_num, 1, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); + } FIX_PRECISION(adjust_precision, precision, s, s_len); break; case 'd': case 'i': - if (is_long) - i_num = va_arg(ap, wide_int); - else - i_num = (wide_int) va_arg(ap, int); - s = conv_10(i_num, 0, &is_negative, + if (var_type == IS_QUAD) { + i_quad = va_arg(ap, widest_int); + s = conv_10_quad(i_quad, 0, &is_negative, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + i_num = (wide_int) va_arg(ap, wide_int); + else if (var_type == IS_SHORT) + i_num = (wide_int) (short) va_arg(ap, int); + else + i_num = (wide_int) va_arg(ap, int); + s = conv_10(i_num, 0, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); + } FIX_PRECISION(adjust_precision, precision, s, s_len); if (is_negative) @@ -729,12 +849,21 @@ case 'o': - if (is_long) - ui_num = va_arg(ap, u_wide_int); - else - ui_num = (u_wide_int) va_arg(ap, unsigned int); - s = conv_p2(ui_num, 3, *fmt, + if (var_type == IS_QUAD) { + ui_quad = va_arg(ap, u_widest_int); + s = conv_p2_quad(ui_quad, 3, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int); + else + ui_num = (u_wide_int) va_arg(ap, unsigned int); + s = conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); + } FIX_PRECISION(adjust_precision, precision, s, s_len); if (alternate_form && *s != '0') { *--s = '0'; @@ -745,12 +874,21 @@ case 'x': case 'X': - if (is_long) - ui_num = (u_wide_int) va_arg(ap, u_wide_int); - else - ui_num = (u_wide_int) va_arg(ap, unsigned int); - s = conv_p2(ui_num, 4, *fmt, + if (var_type == IS_QUAD) { + ui_quad = va_arg(ap, u_widest_int); + s = conv_p2_quad(ui_quad, 4, *fmt, + &num_buf[NUM_BUF_SIZE], &s_len); + } + else { + if (var_type == IS_LONG) + ui_num = (u_wide_int) va_arg(ap, u_wide_int); + else if (var_type == IS_SHORT) + ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int); + else + ui_num = (u_wide_int) va_arg(ap, unsigned int); + s = conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); + } FIX_PRECISION(adjust_precision, precision, s, s_len); if (alternate_form && i_num != 0) { *--s = *fmt; /* 'x' or 'X' */ @@ -840,7 +978,14 @@ case 'n': - *(va_arg(ap, int *)) = cc; + if (var_type == IS_QUAD) + *(va_arg(ap, widest_int *)) = cc; + else if (var_type == IS_LONG) + *(va_arg(ap, long *)) = cc; + else if (var_type == IS_SHORT) + *(va_arg(ap, short *)) = cc; + else + *(va_arg(ap, int *)) = cc; break; /* @@ -850,16 +995,25 @@ case 'p': switch(*++fmt) { /* - * If the pointer size is equal to the size of an unsigned - * integer we convert the pointer to a hex number, otherwise - * we print "%p" to indicate that we don't handle "%p". + * If the pointer size is equal to or smaller than the size + * of the largest unsigned int, we convert the pointer to a + * hex number, otherwise we print "%p" to indicate that we + * don't handle "%p". */ case 'p': - ui_num = (u_wide_int) va_arg(ap, void *); - - if (sizeof(char *) <= sizeof(u_wide_int)) - s = conv_p2(ui_num, 4, 'x', - &num_buf[NUM_BUF_SIZE], &s_len); +#ifdef AP_VOID_P_IS_QUAD + if (sizeof(void *) <= sizeof(u_widest_int)) { + ui_quad = (u_widest_int) va_arg(ap, void *); + s = conv_p2_quad(ui_quad, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#else + if (sizeof(void *) <= sizeof(u_wide_int)) { + ui_num = (u_wide_int) va_arg(ap, void *); + s = conv_p2(ui_num, 4, 'x', + &num_buf[NUM_BUF_SIZE], &s_len); + } +#endif else { s = "%p"; s_len = 2; 1.1 apache-apr/pthreads/src/ap/ap_getpass.c Index: ap_getpass.c =================================================================== /* ==================================================================== * Copyright (c) 1995-1999 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ /* * ap_getpass.c: abstraction to provide for obtaining a password from the * command line in whatever way the OS supports. In the best case, it's a * wrapper for the system library's getpass() routine; otherwise, we * use one we define ourselves. */ #include "ap_config.h" #include <sys/types.h> #include <errno.h> #include "ap.h" #ifdef WIN32 #include <conio.h> #endif #ifndef CHARSET_EBCDIC #define LF 10 #define CR 13 #else /* CHARSET_EBCDIC */ #define LF '\n' #define CR '\r' #endif /* CHARSET_EBCDIC */ #define MAX_STRING_LEN 256 #define ERR_OVERFLOW 5 #ifdef MPE /* * MPE lacks getpass() and a way to suppress stdin echo. So for now, just * issue the prompt and read the results with echo. (Ugh). */ static char *getpass(const char *prompt) { static char password[MAX_STRING_LEN]; fputs(prompt, stderr); gets((char *) &password); if (strlen((char *) &password) > (MAX_STRING_LEN - 1)) { password[MAX_STRING_LEN - 1] = '\0'; } return (char *) &password; } #endif #ifdef WIN32 /* * Windows lacks getpass(). So we'll re-implement it here. */ static char *getpass(const char *prompt) { static char password[MAX_STRING_LEN]; int n = 0; fputs(prompt, stderr); while ((password[n] = _getch()) != '\r') { if (password[n] >= ' ' && password[n] <= '~') { n++; printf("*"); } else { printf("\n"); fputs(prompt, stderr); n = 0; } } password[n] = '\0'; printf("\n"); if (n > (MAX_STRING_LEN - 1)) { password[MAX_STRING_LEN - 1] = '\0'; } return (char *) &password; } #endif /* * Use the OS getpass() routine (or our own) to obtain a password from * the input stream. * * Exit values: * 0: Success * 5: Partial success; entered text truncated to the size of the * destination buffer * * Restrictions: Truncation also occurs according to the host system's * getpass() semantics, or at position 255 if our own version is used, * but the caller is *not* made aware of it. */ API_EXPORT(int) ap_getpass(const char *prompt, char *pwbuf, size_t bufsiz) { char *pw_got; int result = 0; pw_got = getpass(prompt); if (strlen(pw_got) > (bufsiz - 1)) { result = ERR_OVERFLOW; } ap_cpystrn(pwbuf, pw_got, bufsiz); return result; } 1.4 +13 -2 apache-apr/pthreads/src/helpers/GuessOS Index: GuessOS =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/GuessOS,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- GuessOS 1999/03/17 17:00:51 1.3 +++ GuessOS 1999/06/10 06:25:49 1.4 @@ -7,6 +7,8 @@ # addition: Any changes or additions to this script should be # Emailed to the Apache group ([EMAIL PROTECTED]). # +# Initially written by Jim Jagielski for the Apache configuration mechanism +# # Be as similar to the output of config.guess/config.sub # as possible. @@ -114,7 +116,11 @@ echo "i486-whatever-bsdi"; exit 0 ;; - BSD/386:*|BSD/OS:*) + BSD/386|BSD/OS:3.*) + echo "${MACHINE}-whatever-bsdi3"; exit 0 + ;; + + BSD/386:*|BSD/OS:*) echo "${MACHINE}-whatever-bsdi"; exit 0 ;; @@ -237,9 +243,14 @@ Rhapsody:*:*:*) case "${MACHINE}" in - Power*) MACHINE=powerpc ;; + "Power Macintosh") MACHINE=powerpc ;; esac echo "${MACHINE}-apple-rhapsody${RELEASE}"; exit 0 + ;; + + "Mac OS":*:*:*) + MACHINE=`uname -p` + echo "${MACHINE}-apple-macos${RELEASE}"; exit 0 ;; "RISC iX":*) 1.4 +3 -0 apache-apr/pthreads/src/helpers/PrintPath Index: PrintPath =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/PrintPath,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- PrintPath 1999/03/17 17:00:53 1.3 +++ PrintPath 1999/06/10 06:25:49 1.4 @@ -10,6 +10,9 @@ # Usage: # PrintPath [-s] [-pPATHNAME] program [program ...] # +# Initially written by Jim Jagielski for the Apache configuration mechanism +# (with kudos to Kernighan/Pike) +# # This script falls under the Apache License. # See http://www.apache.org/docs/LICENSE 1.4 +64 -2 apache-apr/pthreads/src/helpers/TestCompile Index: TestCompile =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/TestCompile,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- TestCompile 1999/03/17 17:00:57 1.3 +++ TestCompile 1999/06/10 06:25:49 1.4 @@ -22,6 +22,14 @@ # ./helpers/TestCompile sanity # Which does a simple sanity check/test compile # +# ./helpers/TestCompile sizeof <type> +# Which prints out the sizeof <type> (sure would be nice +# if sizeof could be use in preprocessor if's) +# +# ./helpers/TestCompile byteorder +# Which prints out the byte order of the machine +# (12: little endian, 21: big endian) +# # It does these by creating a small mini-makefile, based on # ../Makefile.config and trying to compile a small dummy # program. If the compilation succeeds, we assume the test @@ -32,6 +40,8 @@ # located) if you want to test it out. Configure must # also call it as './helpers/TestCompile' # +# Initially written by Jim Jagielski for the Apache configuration mechanism +# # This script falls under the Apache License. # See http://www.apache.org/docs/LICENSE @@ -39,8 +49,10 @@ cd ./helpers # -# Handle "verbose" and "silent" flags +# Handle "verbose", "silent" and "runit" flags # +VERBOSE=no +RUNIT="no" case "$1" in "-v") VERBOSE="yes" @@ -50,6 +62,10 @@ VERBOSE="no" shift ;; + "-r") + RUNIT="yes" + shift + ;; esac # @@ -74,6 +90,49 @@ echo "int main(void) { $3(); return(0); }" > testfunc.c fi ;; + "sizeof") + if [ "x$2" = "x" ]; then + exit + fi + TLIB="" + if [ "x$VERBOSE" = "xyes" ]; then + ERRDIR="" + else + ERRDIR='2>/dev/null' + fi + TARGET='testfunc' + cat <<EOF >testfunc.c +#include <stdio.h> +#include <sys/types.h> +int main(void) { + printf("%d\n", sizeof($2)); + return(0); +} +EOF + ;; + "byteorder") + TLIB="" + if [ "x$VERBOSE" = "xyes" ]; then + ERRDIR="" + else + ERRDIR='2>/dev/null' + fi + TARGET='testfunc' + cat <<EOF >testfunc.c +#include <stdio.h> +#include <sys/types.h> +int main(void) { + /* Are we little or big endian? From Harbison & Steele */ + union { + long l; + char c[sizeof(long)]; + } u; + u.l = 1; + printf("%s\n", u.c[sizeof(long)-1] == 1 ? "21" : "12"); + return(0); +} +EOF + ;; "sanity") TLIB="" if [ "x$VERBOSE" = "xno" ]; then @@ -143,7 +202,7 @@ EOF # Now run that Makefile -eval "${MAKE} ${TARGET} >/dev/null $ERRDIR" +eval "${MAKE-make} ${TARGET} $ERRDIR >&2" # And see if dummy exists and is executable, if so, then we # assume the condition we are testing for is good @@ -152,5 +211,8 @@ # have PrintPath just search this directory. if ./PrintPath -s -p`pwd` $TARGET ; then + if [ "x$RUNIT" = "xyes" ]; then + `pwd`/$TARGET + fi exstat=0 fi 1.3 +93 -21 apache-apr/pthreads/src/helpers/binbuild.sh Index: binbuild.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/binbuild.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- binbuild.sh 1999/03/17 17:00:58 1.2 +++ binbuild.sh 1999/06/10 06:25:49 1.3 @@ -7,16 +7,22 @@ # See http://www.apache.org/docs/LICENSE +CONFIGPARAM="--with-layout=BinaryDistribution --enable-module=most --enable-shared=max" APDIR=`pwd` APDIR=`basename $APDIR` VER=`echo $APDIR |sed s/apache_//` OS=`src/helpers/GuessOS` -USER="`src/helpers/buildinfo.sh -n [EMAIL PROTECTED]" TAR="`src/helpers/PrintPath tar`" GTAR="`src/helpers/PrintPath gtar`" GZIP="`src/helpers/PrintPath gzip`" -CONFIGPARAM="--with-layout=BinaryDistribution --enable-module=most --enable-shared=max" +if [ x$1 != x ] +then + USER=$1 +else + USER="`src/helpers/buildinfo.sh -n [EMAIL PROTECTED]" +fi + if [ ! -f ./ABOUT_APACHE ] then echo "ERROR: The current directory contains no valid Apache distribution." @@ -59,7 +65,10 @@ exit 1; fi -echo "Binary images successfully created..." +echo "Binary image successfully created..." + +./bindist/bin/httpd -v + echo "Creating supplementary files..." ( echo " " && \ @@ -120,6 +129,64 @@ echo "# This script installs the Apache binary distribution and" && \ echo "# was automatically created by binbuild.sh." && \ echo " " && \ + echo "lmkdir()" && \ + echo "{" && \ + echo " path=\"\"" && \ + echo " dirs=\`echo \$1 | sed -e 's%/% %g'\`" && \ + echo " mode=\$2" && \ + echo " " && \ + echo " set -- \${dirs}" && \ + echo " " && \ + echo " for d in \${dirs}" && \ + echo " do" && \ + echo " path=\"\${path}/\$d\"" && \ + echo " if test ! -d \"\${path}\" ; then" && \ + echo " mkdir \${path}" && \ + echo " if test \$? -ne 0 ; then" && \ + echo " echo \"Failed to create directory: \${path}\"" && \ + echo " exit 1" && \ + echo " fi" && \ + echo " chmod \${mode} \${path}" && \ + echo " fi" && \ + echo " done" && \ + echo "}" && \ + echo " " && \ + echo "lcopy()" && \ + echo "{" && \ + echo " from=\$1" && \ + echo " to=\$2" && \ + echo " dmode=\$3" && \ + echo " fmode=\$4" && \ + echo " " && \ + echo " test -d \${to} || lmkdir \${to} \${dmode}" && \ + echo " (cd \${from} && tar -cf - *) | (cd \${to} && tar -xf -)" && \ + echo " " && \ + echo " if test \"X\${fmode}\" != X ; then" && \ + echo " find \${to} -type f -print | xargs chmod \${fmode}" && \ + echo " fi" && \ + echo " if test \"X\${dmode}\" != X ; then" && \ + echo " find \${to} -type d -print | xargs chmod \${dmode}" && \ + echo " fi" && \ + echo "}" && \ + echo " " && \ + echo "##" && \ + echo "## determine path to (optional) Perl interpreter" && \ + echo "##" && \ + echo "PERL=no-perl5-on-this-system" && \ + echo "perls='perl5 perl'" && \ + echo "path=\`echo \$PATH | sed -e 's/:/ /g'\`" && \ + echo " " && \ + echo "for dir in \${path} ; do" && \ + echo " for pperl in \${perls} ; do" && \ + echo " if test -f \"\${dir}/\${pperl}\" ; then" && \ + echo " if \`\${dir}/\${pperl} -v | grep 'version 5\.' >/dev/null 2>&1\` ; then" && \ + echo " PERL=\"\${dir}/\${pperl}\"" && \ + echo " break" && \ + echo " fi" && \ + echo " fi" && \ + echo " done" && \ + echo "done" && \ + echo " " && \ echo "if [ .\$1 = . ]" && \ echo "then" && \ echo " SR=/usr/local/apache" && \ @@ -128,41 +195,46 @@ echo "fi" && \ echo "echo \"Installing binary distribution for platform $OS\"" && \ echo "echo \"into directory \$SR ...\"" && \ - echo "./src/helpers/mkdir.sh \$SR" && \ - echo "cp -r bindist/proxy \$SR/proxy" && \ - echo "cp -r bindist/man \$SR/man" && \ - echo "cp -r bindist/logs \$SR/logs" && \ - echo "cp -r bindist/libexec \$SR/libexec" && \ - echo "cp -r bindist/include \$SR/include" && \ - echo "cp -r bindist/icons \$SR/icons" && \ - echo "cp -r bindist/cgi-bin \$SR/cgi-bin" && \ - echo "cp -r bindist/bin \$SR/bin" && \ + echo "lmkdir \$SR 755" && \ + echo "lmkdir \$SR/proxy 750" && \ + echo "lmkdir \$SR/logs 750" && \ + echo "lcopy bindist/man \$SR/man 755 644" && \ + echo "lcopy bindist/libexec \$SR/libexec 750 644" && \ + echo "lcopy bindist/include \$SR/include 755 644" && \ + echo "lcopy bindist/icons \$SR/icons 755 644" && \ + echo "lcopy bindist/cgi-bin \$SR/cgi-bin 750 750" && \ + echo "lcopy bindist/bin \$SR/bin 750 750" && \ echo "if [ -d \$SR/conf ]" && \ echo "then" && \ echo " echo \"[Preserving existing configuration files.]\"" && \ - echo " cp -r bindist/conf/*.default \$SR/conf/" && \ + echo " cp bindist/conf/*.default \$SR/conf/" && \ echo "else" && \ - echo " cp -r bindist/conf \$SR/conf" && \ + echo " lcopy bindist/conf \$SR/conf 750 640" && \ echo "fi" && \ echo "if [ -d \$SR/htdocs ]" && \ echo "then" && \ echo " echo \"[Preserving existing htdocs directory.]\"" && \ echo "else" && \ - echo " cp -r bindist/htdocs \$SR/htdocs" && \ + echo " lcopy bindist/htdocs \$SR/htdocs 755 644" && \ echo "fi" && \ - echo "sed -e s%/usr/local/apache%\$SR/% \$SR/conf/httpd.conf.default > \$SR/conf/httpd.conf" && \ - echo "sed -e s%PIDFILE=%PIDFILE=\$SR/% -e s%HTTPD=%HTTPD=\\\"\$SR/% -e \"s%/httpd$%/httpd -d \$SR\\\"%\" bindist/bin/apachectl > \$SR/bin/apachectl" && \ + echo " " && \ + echo "sed -e \"s;^#!/.*;#!\$PERL;\" -e \"s;[EMAIL PROTECTED]@;\$SR;\" -e \"s;[EMAIL PROTECTED]@;\$SR/bin;\" \\" && \ + echo " -e \"s;[EMAIL PROTECTED]@;\$SR/libexec;\" -e \"s;[EMAIL PROTECTED]@;\$SR/include;\" \\" && \ + echo " -e \"s;[EMAIL PROTECTED]@;\$SR/conf;\" bindist/bin/apxs > \$SR/bin/apxs" && \ + echo "sed -e \"s;^#!/.*;#!\$PERL;\" bindist/bin/dbmmanage > \$SR/bin/dbmmanage" && \ + echo "sed -e \"s%/usr/local/apache%\$SR/%\" \$SR/conf/httpd.conf.default > \$SR/conf/httpd.conf" && \ + echo "sed -e \"s%PIDFILE=%PIDFILE=\$SR/%\" -e \"s%HTTPD=%HTTPD=\\\"\$SR/%\" -e \"s%httpd\$%httpd -d \$SR\\\"%\" bindist/bin/apachectl > \$SR/bin/apachectl" && \ echo " " && \ echo "echo \"Ready.\"" && \ echo "echo \" +--------------------------------------------------------+\"" && \ echo "echo \" | You now have successfully installed the Apache $VER |\"" && \ echo "echo \" | HTTP server. To verify that Apache actually works |\"" && \ - echo "echo \" | correctly you now should first check the (initially |\"" && \ - echo "echo \" | created or preserved) configuration files |\"" && \ + echo "echo \" | correctly you should first check the (initially |\"" && \ + echo "echo \" | created or preserved) configuration files: |\"" && \ echo "echo \" | |\"" && \ echo "echo \" | \$SR/conf/httpd.conf\"" && \ echo "echo \" | |\"" && \ - echo "echo \" | and then you should be able to immediately fire up |\"" && \ + echo "echo \" | You should then be able to immediately fire up |\"" && \ echo "echo \" | Apache the first time by running: |\"" && \ echo "echo \" | |\"" && \ echo "echo \" | \$SR/bin/apachectl start \"" &&\ @@ -192,7 +264,7 @@ else if [ "x$GTAR" != "x" ] then - $GTAR -zcf ../apache_$VER-$OS.tar.gz -C .. --owner=root --group=root apache_$VER + $GTAR -zcf ../apache_$VER-$OS.tar.gz -C .. apache_$VER else if [ "x$TAR" != "x" ] then 1.4 +1 -1 apache-apr/pthreads/src/helpers/buildinfo.sh Index: buildinfo.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/buildinfo.sh,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- buildinfo.sh 1999/03/17 17:00:58 1.3 +++ buildinfo.sh 1999/06/10 06:25:49 1.4 @@ -1,7 +1,7 @@ #!/bin/sh ## ## buildinfo.sh -- Determine Build Information -## Written by Ralf S. Engelschall <[EMAIL PROTECTED]> +## Initially written by Ralf S. Engelschall <[EMAIL PROTECTED]> ## for the Apache's Autoconf-style Interface (APACI) ## # 1.3 +2 -1 apache-apr/pthreads/src/helpers/checkheader.sh Index: checkheader.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/checkheader.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- checkheader.sh 1999/02/07 06:29:16 1.2 +++ checkheader.sh 1999/06/10 06:25:49 1.3 @@ -1,7 +1,8 @@ #!/bin/sh ## ## checkheader.sh -- Check whether a C header file exists -## Written by Ralf S. Engelschall for the Apache configuration mechanism +## Initially written by Ralf S. Engelschall for the Apache +## configuration mechanism ## # # This script falls under the Apache License. 1.2 +1 -1 apache-apr/pthreads/src/helpers/dummy.c Index: dummy.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/dummy.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- dummy.c 1999/01/21 23:08:32 1.1 +++ dummy.c 1999/06/10 06:25:49 1.2 @@ -6,7 +6,7 @@ return *c; } int main(void) { - const char *c = '\0'; + const char *c = ""; (void)foo(c); return 0; } 1.3 +2 -1 apache-apr/pthreads/src/helpers/findcpp.sh Index: findcpp.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/findcpp.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- findcpp.sh 1999/02/07 06:29:17 1.2 +++ findcpp.sh 1999/06/10 06:25:50 1.3 @@ -1,7 +1,8 @@ #!/bin/sh ## ## findcpp.sh -- Find out how to _directly_ run the C Pre-Processor (CPP) -## Written by Ralf S. Engelschall for the Apache configuration mechanism +## Initially written by Ralf S. Engelschall for the Apache configuration +## mechanism ## # # This script falls under the Apache License. 1.3 +1 -2 apache-apr/pthreads/src/helpers/fmn.sh Index: fmn.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/fmn.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- fmn.sh 1999/02/07 06:29:17 1.2 +++ fmn.sh 1999/06/10 06:25:50 1.3 @@ -2,8 +2,7 @@ ## ## fmn.sh -- find a modules (structure) name ## -## Extracted from the Configure script by -## Ralf S. Engelschall <[EMAIL PROTECTED]> for use with +## Extracted from the Configure script for use with ## Apache's Autoconf-style Interface (APACI). ## # 1.4 +8 -0 apache-apr/pthreads/src/helpers/install.sh Index: install.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/install.sh,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- install.sh 1999/03/17 17:00:59 1.3 +++ install.sh 1999/06/10 06:25:50 1.4 @@ -34,6 +34,7 @@ stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" +ext="" src="" dst="" while [ "x$1" != "x" ]; do @@ -56,6 +57,9 @@ -S) stripcmd="$stripprog $2" shift; shift; continue ;; + -e) ext="$2" + shift; shift; continue + ;; *) if [ "x$src" = "x" ]; then src=$1 else @@ -82,6 +86,10 @@ if [ -d $dst ]; then dst="$dst/`basename $src`" fi + +# Add a possible extension (such as ".exe") to src and dst +src="$src$ext" +dst="$dst$ext" # Make a temp file name in the proper directory. dstdir=`dirname $dst` 1.3 +1 -1 apache-apr/pthreads/src/helpers/mkshadow.sh Index: mkshadow.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/mkshadow.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mkshadow.sh 1999/02/07 06:29:17 1.2 +++ mkshadow.sh 1999/06/10 06:25:50 1.3 @@ -2,7 +2,7 @@ ## ## mkshadow.sh -- create a shadow tree ## -## Written by Ralf S. Engelschall <[EMAIL PROTECTED]> +## Initially written by Ralf S. Engelschall <[EMAIL PROTECTED]> ## for the shadow tree generation option (--shadow) of ## Apache's Autoconf-style Interface (APACI) ## 1.3 +1 -1 apache-apr/pthreads/src/helpers/ppl.sh Index: ppl.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/ppl.sh,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- ppl.sh 1999/02/07 06:29:17 1.2 +++ ppl.sh 1999/06/10 06:25:50 1.3 @@ -4,7 +4,7 @@ ## `tr' and `fmt' because these tools are different ## between Unix platforms ## -## Written by Ralf S. Engelschall <[EMAIL PROTECTED]> +## Initially written by Ralf S. Engelschall <[EMAIL PROTECTED]> ## for pretty printing lists in the --help option of ## Apache's Autoconf-style Interface (APACI) ## 1.4 +1 -1 apache-apr/pthreads/src/helpers/slo.sh Index: slo.sh =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/helpers/slo.sh,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- slo.sh 1999/03/17 17:01:00 1.3 +++ slo.sh 1999/06/10 06:25:50 1.4 @@ -1,7 +1,7 @@ #!/bin/sh ## ## slo.h -- (S)eparate (L)inker (O)ptions by library class -## Written by Ralf S. Engelschall <[EMAIL PROTECTED]> +## Initially written by Ralf S. Engelschall <[EMAIL PROTECTED]> ## # # This script falls under the Apache License. 1.1 apache-apr/pthreads/src/helpers/getuid.sh Index: getuid.sh =================================================================== #!/bin/sh # Return the uid of the process being run. If we cannot # determine what it is, return '?'. # # Initially written by Jim Jagielski for the Apache configuration mechanism # # This script falls under the Apache License. # See http://www.apache.org/docs/LICENSE # First we try 'id' if `./src/helpers/PrintPath -s id` ; then AP_IDPATH=`./src/helpers/PrintPath id` # See if it's a POSIX 'id' if `$AP_IDPATH -u >/dev/null 2>&1` ; then AP_RETVAL=`$AP_IDPATH -u` echo $AP_RETVAL exit 0 else AP_RETVAL=`$AP_IDPATH | \ sed -e 's/^.*uid[ ]*=[ ]*[^0123456789]*//' | \ sed -e 's/[ ]*(.*$//'` echo $AP_RETVAL exit 0 fi fi # # Ugg. Now we have to grab the login name of the process, and # scan /etc/passwd. # # Try 'whoami' first, then 'who am i' (making sure to strip away # the who crud) and finally just copy $LOGNAME # if `./src/helpers/PrintPath -s whoami` ; then AP_WAIPATH=`./src/helpers/PrintPath whoami` AP_LOGNAME=`$AP_WAIPATH` else AP_LOGNAME=`who am i | tail -1 | sed -e 's/[ ][ ]*.*$//'` fi # # See if we have a valid login name. # if [ "x$AP_LOGNAME" = "x" ]; then AP_LOGNAME=$LOGNAME if [ "x$AP_LOGNAME" = "x" ]; then echo "?" exit 1 fi fi # # Ok, now we scan through /etc/passwd # AP_RETVAL=`egrep \^${AP_LOGNAME}: /etc/passwd | \ sed -e 's/[^:]*:[^:]*://' | \ sed -e 's/:.*$//'` if [ "x$AP_RETVAL" = "x" ]; then echo "?" exit 1 else echo $AP_RETVAL exit 0 fi 1.6 +36 -2 apache-apr/pthreads/src/include/alloc.h Index: alloc.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/alloc.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -u -r1.5 -r1.6 --- alloc.h 1999/04/09 04:10:34 1.5 +++ alloc.h 1999/06/10 06:25:53 1.6 @@ -97,8 +97,42 @@ API_EXPORT(pool *) ap_make_root_pool(void); API_EXPORT(void) ap_destroy_pool(pool *); -/* used to guarantee to the pool debugging code that the sub pool will not be - * destroyed before the parent pool +/* pools have nested lifetimes -- sub_pools are destroyed when the + * parent pool is cleared. We allow certain liberties with operations + * on things such as tables (and on other structures in a more general + * sense) where we allow the caller to insert values into a table which + * were not allocated from the table's pool. The table's data will + * remain valid as long as all the pools from which its values are + * allocated remain valid. + * + * For example, if B is a sub pool of A, and you build a table T in + * pool B, then it's safe to insert data allocated in A or B into T + * (because B lives at most as long as A does, and T is destroyed when + * B is cleared/destroyed). On the other hand, if S is a table in + * pool A, it is safe to insert data allocated in A into S, but it + * is *not safe* to insert data allocated from B into S... because + * B can be cleared/destroyed before A is (which would leave dangling + * pointers in T's data structures). + * + * In general we say that it is safe to insert data into a table T + * if the data is allocated in any ancestor of T's pool. This is the + * basis on which the POOL_DEBUG code works -- it tests these ancestor + * relationships for all data inserted into tables. POOL_DEBUG also + * provides tools (ap_find_pool, and ap_pool_is_ancestor) for other + * folks to implement similar restrictions for their own data + * structures. + * + * However, sometimes this ancestor requirement is inconvenient -- + * sometimes we're forced to create a sub pool (such as through + * ap_sub_req_lookup_uri), and the sub pool is guaranteed to have + * the same lifetime as the parent pool. This is a guarantee implemented + * by the *caller*, not by the pool code. That is, the caller guarantees + * they won't destroy the sub pool individually prior to destroying the + * parent pool. + * + * In this case the caller must call ap_pool_join() to indicate this + * guarantee to the POOL_DEBUG code. There are a few examples spread + * through the standard modules. */ #ifndef POOL_DEBUG #ifdef ap_pool_join 1.3 +1 -0 apache-apr/pthreads/src/include/ap.h Index: ap.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/ap.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- ap.h 1999/02/07 06:29:20 1.2 +++ ap.h 1999/06/10 06:25:54 1.3 @@ -71,6 +71,7 @@ APRFile ap_slack(APRFile, int); int ap_execle(const char *, const char *, ...); int ap_execve(const char *, const char *argv[], const char *envp[]); +API_EXPORT(int) ap_getpass(const char *prompt, char *pwbuf, size_t bufsiz); /* small utility macros to make things easier to read */ 1.3 +4 -0 apache-apr/pthreads/src/include/ap_compat.h Index: ap_compat.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/ap_compat.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- ap_compat.h 1999/02/07 06:29:20 1.2 +++ ap_compat.h 1999/06/10 06:25:54 1.3 @@ -23,6 +23,7 @@ #define acquire_mutex ap_acquire_mutex #define add_cgi_vars ap_add_cgi_vars #define add_common_vars ap_add_common_vars +#define add_file_conf ap_add_file_conf #define add_module ap_add_module #define add_named_module ap_add_named_module #define add_per_dir_conf ap_add_per_dir_conf @@ -301,6 +302,8 @@ #define rationalize_mtime ap_rationalize_mtime #define read_config ap_read_config #define read_request ap_read_request +#define regexec ap_regexec +#define regerror ap_regerror #define register_cleanup ap_register_cleanup #define register_other_child ap_register_other_child #define release_mutex ap_release_mutex @@ -346,6 +349,7 @@ #define server_root_relative ap_server_root_relative #define set_byterange ap_set_byterange #define set_callback_and_alarm ap_set_callback_and_alarm +#define set_config_vectors ap_set_config_vectors #define set_content_length ap_set_content_length #define set_etag ap_set_etag #define set_file_slot ap_set_file_slot 1.6 +92 -22 apache-apr/pthreads/src/include/ap_config.h Index: ap_config.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/ap_config.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -u -r1.5 -r1.6 --- ap_config.h 1999/04/14 07:32:45 1.5 +++ ap_config.h 1999/06/10 06:25:54 1.6 @@ -376,10 +376,6 @@ #endif #ifndef S_IWOTH #define S_IWOTH 000002 -#ifndef rlim_t -typedef int rlim_t; -#endif -typedef u_long n_long; #endif #define STDIN_FILENO 0 @@ -397,12 +393,28 @@ #define NO_USE_SIGACTION #define HAVE_SYSLOG 1 -#elif defined(RHAPSODY) /* Mac OS X Server */ +#if defined(__DYNAMIC__) +#define HAVE_DYLD +#define DYLD_CANT_UNLOAD +#endif + +#elif defined(MAC_OS) || defined(MAC_OS_X_SERVER) /* Mac OS (>= 10.0) and Mac OS X Server (<= 5.x) */ +#ifdef MAC_OS_X_SERVER +#define PLATFORM "Mac OS X Server" +#else +#define PLATFORM "Mac OS" +#endif +#define HAVE_DYLD +#ifdef MAC_OS_X_SERVER +#define DYLD_CANT_UNLOAD +#endif /* MAC_OS_X_SERVER */ #define HAVE_GMTOFF #define HAVE_MMAP #define USE_MMAP_FILES #define USE_MMAP_SCOREBOARD +#ifdef MAC_OS_X_SERVER #define MAP_TMPFILE +#endif /* MAC_OS_X_SERVER */ #define HAVE_RESOURCE #define HAVE_SNPRINTF #define JMP_BUF jmp_buf @@ -410,26 +422,52 @@ #define USE_FLOCK_SERIALIZED_ACCEPT #define SINGLE_LISTEN_UNSERIALIZED_ACCEPT /* - * If you are using APACI, (you should be on Rhapsody) these - * values are set at configure time. These are here as reference; - * the apache that is built into Rhapsody is configured with - * these values. + * If you are using APACI, (you probably should be on Mac OS) these + * values are set at configure time. */ -#if 0 +#ifndef HTTPD_ROOT #define HTTPD_ROOT "/Local/Library/WebServer" +#endif +#ifndef DOCUMENT_LOCATION #define DOCUMENT_LOCATION HTTPD_ROOT "/Documents" +#endif +#ifndef DEFAULT_XFERLOG #define DEFAULT_XFERLOG "Logs/Access" +#endif +#ifndef DEFAULT_ERRORLOG #define DEFAULT_ERRORLOG "Logs/Errors" +#endif +#ifndef DEFAULT_PIDLOG #define DEFAULT_PIDLOG "Logs/Process" +#endif +#ifndef DEFAULT_SCOREBOARD #define DEFAULT_SCOREBOARD "Logs/Status" +#endif +#ifndef DEFAULT_LOCKFILE #define DEFAULT_LOCKFILE "Logs/Lock" +#endif +#ifndef SERVER_CONFIG_FILE #define SERVER_CONFIG_FILE "Configuration/Server" +#endif +#ifndef RESOURCE_CONFIG_FILE #define RESOURCE_CONFIG_FILE "Configuration/Resources" +#endif +#ifndef TYPES_CONFIG_FILE #define TYPES_CONFIG_FILE "Configuration/MIME" +#endif +#ifndef ACCESS_CONFIG_FILE #define ACCESS_CONFIG_FILE "Configuration/Access" +#endif +#ifndef DEFAULT_USER_DIR #define DEFAULT_USER_DIR "Library/Web Documents" -#define DEFAULT_USER "nobody" -#define DEFAULT_GROUP "nogroup" +#endif +#ifndef DEFAULT_USER +#define DEFAULT_USER "www" +#endif +#ifndef DEFAULT_GROUP +#define DEFAULT_GROUP "www" +#endif +#ifndef DEFAULT_PATH #define DEFAULT_PATH "/bin:/usr/bin:/usr/local/bin" #endif @@ -755,13 +793,14 @@ #define NO_KILLPG #define NEED_STRCASECMP #define NEED_STRNCASECMP +#define NEED_PROCESS_H #define NO_SETSID #define NO_TIMES #define CASE_BLIND_FILESYSTEM /* Add some drive name support */ #define chdir _chdir2 #include <sys/time.h> -#define MAXSOCKETS 4096 +#define MAXSOCKETS 2048 #define USE_OS2_SCOREBOARD #define NO_RELIABLE_PIPED_LOGS #define USE_OS2SEM_SERIALIZED_ACCEPT @@ -861,10 +900,16 @@ #include <sysgtime.h> #define PRIMECRAS 0x010000 #define JMP_BUF jmp_buf +#define HAVE_SHMGET +#undef HAVE_SYS_RESOURCE_H #define NEED_INITGROUPS +#define NEED_SIGNAL_INTERRUPT +#include <strings.h> +#ifndef __strings_h #define NEED_STRCASECMP -#define NEED_STRDUP #define NEED_STRNCASECMP +#endif +#define NEED_STRDUP #define NO_DBM_REWRITEMAP #define NO_GETTIMEOFDAY #define NO_KILLPG @@ -873,12 +918,16 @@ #define NO_OTHER_CHILD #define NO_RELIABLE_PIPED_LOGS #define NO_SETSID -#define NO_SHMGET #define NO_SLACK #define NO_TIMES #define NO_USE_SIGACTION #define NO_WRITEV #define USE_LONGJMP +/*#define USE_SHMGET_SCOREBOARD*/ +#define USE_TPF_ACCEPT +#define USE_TPF_CORE_SERIALIZED_ACCEPT +/*#define USE_TPF_DAEMON*/ +#define USE_TPF_SCOREBOARD #define USE_TPF_SELECT #undef offsetof #define offsetof(s_type,field) ((size_t)&(((s_type*)0)->field)) @@ -936,7 +985,7 @@ * __private_extern__. * For other systems, make that a no-op. */ -#if defined(RHAPSODY) +#if defined(MAC_OS) || defined(MAC_OS_X_SERVER) #define ap_private_extern __private_extern__ #else #define ap_private_extern @@ -987,7 +1036,6 @@ #include <pwd.h> #include <grp.h> #include <fcntl.h> -#include <limits.h> #define closesocket(s) close(s) #ifndef O_BINARY #define O_BINARY (0) @@ -999,12 +1047,15 @@ #include <io.h> #include <fcntl.h> #endif /* ndef WIN32 */ - +#include <limits.h> #include <time.h> /* for ctime */ #ifdef WIN32 #define strftime(s,max,format,tm) os_strftime(s,max,format,tm) #endif #include <signal.h> +#if defined(TPF) && defined(NSIG) +#undef NSIG +#endif #include <errno.h> #if !defined(QNX) && !defined(CONVEXOS11) && !defined(NEXT) && !defined(TPF) #include <memory.h> @@ -1103,13 +1154,32 @@ #endif #endif -#ifdef SELECT_NEEDS_CAST +/* Majority of os's want to verify FD_SETSIZE */ +#if !defined(WIN32) && !defined(TPF) +#define CHECK_FD_SETSIZE +#endif + +#ifdef USE_TPF_SELECT #define ap_select(_a, _b, _c, _d, _e) \ + tpf_select(_a, _b, _c, _d, _e) +#elif defined(SELECT_NEEDS_CAST) +#define ap_select(_a, _b, _c, _d, _e) \ select((_a), (int *)(_b), (int *)(_c), (int *)(_d), (_e)) -#elif defined(USE_TPF_SELECT) -#define ap_select tpf_select #else -#define ap_select select +#define ap_select(_a, _b, _c, _d, _e) \ + select(_a, _b, _c, _d, _e) +#endif + +#ifdef USE_TPF_ACCEPT +#define ap_accept(_fd, _sa, _ln) tpf_accept(_fd, _sa, _ln) +#else +#define ap_accept(_fd, _sa, _ln) accept(_fd, _sa, _ln) +#endif + +#ifdef NEED_SIGNAL_INTERRUPT +#define ap_check_signals() tpf_process_signals() +#else +#define ap_check_signals() #endif #ifdef ULTRIX_BRAIN_DEATH 1.3 +6 -5 apache-apr/pthreads/src/include/ap_md5.h Index: ap_md5.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/ap_md5.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- ap_md5.h 1999/02/07 06:29:21 1.2 +++ ap_md5.h 1999/06/10 06:25:55 1.3 @@ -104,11 +104,12 @@ unsigned char buffer[64]; /* input buffer */ } AP_MD5_CTX; -API_EXPORT(void) ap_MD5Init(AP_MD5_CTX * context); -API_EXPORT(void) ap_MD5Update(AP_MD5_CTX * context, const unsigned char *input, - unsigned int inputLen); -API_EXPORT(void) ap_MD5Final(unsigned char digest[16], AP_MD5_CTX * context); -API_EXPORT(void) ap_MD5Encode(const char *password, const char *salt, +API_EXPORT(void) ap_MD5Init(AP_MD5_CTX *context); +API_EXPORT(void) ap_MD5Update(AP_MD5_CTX *context, const unsigned char *input, + unsigned int inputLen); +API_EXPORT(void) ap_MD5Final(unsigned char digest[16], AP_MD5_CTX *context); +API_EXPORT(void) ap_MD5Encode(const unsigned char *password, + const unsigned char *salt, char *result, size_t nbytes); API_EXPORT(char *) ap_validate_password(const char *passwd, const char *hash); 1.4 +8 -2 apache-apr/pthreads/src/include/ap_mmn.h Index: ap_mmn.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/ap_mmn.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- ap_mmn.h 1999/03/17 17:01:08 1.3 +++ ap_mmn.h 1999/06/10 06:25:55 1.4 @@ -213,14 +213,20 @@ * definition of method in request_rec. * 19990108.6 - SIGPIPE is now ignored by the core server. * 19990108.7 - ap_isxdigit added + * 19990320 - METHODS and M_INVALID symbol values modified + * 19990320.1 - add ap_vrprintf() + * 19990320.2 - add cmd_parms.context, ap_set_config_vectors, + * export ap_add_file_conf + * 19990320.3 - add ap_regexec() + * 19990604.4 - add ap_field_noparam() */ #define MODULE_MAGIC_COOKIE 0x41503133UL /* "AP13" */ #ifndef MODULE_MAGIC_NUMBER_MAJOR -#define MODULE_MAGIC_NUMBER_MAJOR 19990108 +#define MODULE_MAGIC_NUMBER_MAJOR 19990320 #endif -#define MODULE_MAGIC_NUMBER_MINOR 7 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 4 /* 0...n */ #define MODULE_MAGIC_NUMBER MODULE_MAGIC_NUMBER_MAJOR /* backward compat */ /* Useful for testing for features. */ 1.2 +1 -1 apache-apr/pthreads/src/include/hsregex.h Index: hsregex.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/hsregex.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- hsregex.h 1999/01/21 23:08:32 1.1 +++ hsregex.h 1999/06/10 06:25:55 1.2 @@ -16,7 +16,7 @@ #endif #endif -#if defined(RHAPSODY) +#if defined(MAC_OS) || defined(MAC_OS_X_SERVER) #define ap_private_extern __private_extern__ #else #define ap_private_extern 1.4 +3 -0 apache-apr/pthreads/src/include/http_config.h Index: http_config.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/http_config.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- http_config.h 1999/03/17 17:01:09 1.3 +++ http_config.h 1999/06/10 06:25:55 1.4 @@ -170,6 +170,8 @@ */ const command_rec *cmd; /* configuration command */ const char *end_token; /* end token required to end a nested section */ + void *context; /* per_dir_config vector passed + * to handle_command */ } cmd_parms; /* This structure records the existence of handlers in a module... */ @@ -400,6 +402,7 @@ CORE_EXPORT(const command_rec *) ap_find_command(const char *name, const command_rec *cmds); CORE_EXPORT(const command_rec *) ap_find_command_in_modules(const char *cmd_name, module **mod); +CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module *mod); CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, const char *l); #endif 1.3 +3 -1 apache-apr/pthreads/src/include/http_core.h Index: http_core.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/http_core.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- http_core.h 1999/02/07 06:29:21 1.2 +++ http_core.h 1999/06/10 06:25:56 1.3 @@ -251,7 +251,8 @@ unsigned long limit_req_body; /* limit on bytes in request msg body */ /* logging options */ - enum { srv_sig_off, srv_sig_on, srv_sig_withmail } server_signature; + enum { srv_sig_unset, srv_sig_off, srv_sig_on, + srv_sig_withmail } server_signature; int loglevel; /* Access control */ @@ -292,6 +293,7 @@ /* for mod_perl */ CORE_EXPORT(void) ap_add_per_dir_conf (server_rec *s, void *dir_config); CORE_EXPORT(void) ap_add_per_url_conf (server_rec *s, void *url_config); +CORE_EXPORT(void) ap_add_file_conf(core_dir_config *conf, void *url_config); CORE_EXPORT_NONSTD(const char *) ap_limit_section (cmd_parms *cmd, void *dummy, const char *arg); #endif 1.3 +1 -0 apache-apr/pthreads/src/include/http_protocol.h Index: http_protocol.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/http_protocol.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- http_protocol.h 1999/02/07 06:29:22 1.2 +++ http_protocol.h 1999/06/10 06:25:56 1.3 @@ -148,6 +148,7 @@ API_EXPORT(int) ap_rputs(const char *str, request_rec *r); API_EXPORT(int) ap_rwrite(const void *buf, int nbyte, request_rec *r); API_EXPORT_NONSTD(int) ap_rvputs(request_rec *r,...); +API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list vlist); API_EXPORT_NONSTD(int) ap_rprintf(request_rec *r, const char *fmt,...) __attribute__((format(printf,2,3))); API_EXPORT(int) ap_rflush(request_rec *r); 1.17 +26 -4 apache-apr/pthreads/src/include/httpd.h Index: httpd.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/httpd.h,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -u -r1.16 -r1.17 --- httpd.h 1999/06/09 22:06:29 1.16 +++ httpd.h 1999/06/10 06:25:56 1.17 @@ -442,7 +442,7 @@ * Always increases along the same track as the source branch. * For example, Apache 1.4.2 would be '10402100', 2.5b7 would be '20500007'. */ -#define APACHE_RELEASE 10305000 +#define APACHE_RELEASE 10307000 #define SERVER_PROTOCOL "HTTP/1.1" #ifndef SERVER_SUPPORT @@ -568,9 +568,9 @@ #define M_MOVE 12 #define M_LOCK 13 #define M_UNLOCK 14 +#define M_INVALID 15 -#define METHODS 15 -#define M_INVALID 31 +#define METHODS 16 #define CGI_MAGIC_TYPE "application/x-httpd-cgi" #define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html" @@ -583,6 +583,23 @@ #define DIR_MAGIC_TYPE "httpd/unix-directory" #define STATUS_MAGIC_TYPE "application/x-httpd-status" +/* + * Define the HTML doctype strings centrally. + */ +#define DOCTYPE_HTML_2_0 "<!DOCTYPE HTML PUBLIC \"-//IETF//" \ + "DTD HTML 2.0//EN\">\n" +#define DOCTYPE_HTML_3_2 "<!DOCTYPE HTML PUBLIC \"-//W3C//" \ + "DTD HTML 3.2 Final//EN\">\n" +#define DOCTYPE_HTML_4_0S "<!DOCTYPE HTML PUBLIC \"-//W3C//" \ + "DTD HTML 4.0//EN\"\n" \ + "\"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" +#define DOCTYPE_HTML_4_0T "<!DOCTYPE HTML PUBLIC \"-//W3C//" \ + "DTD HTML 4.0 Transitional//EN\"\n" \ + "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n" +#define DOCTYPE_HTML_4_0F "<!DOCTYPE HTML PUBLIC \"-//W3C//" \ + "DTD HTML 4.0 Frameset//EN\"\n" \ + "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" + /* Just in case your linefeed isn't the one the other end is expecting. */ #ifndef CHARSET_EBCDIC #define LF 10 @@ -931,6 +948,7 @@ API_EXPORT(struct tm *) ap_get_gmtoff(int *tz); API_EXPORT(char *) ap_get_time(void); +API_EXPORT(char *) ap_field_noparam(pool *p, const char *intype); API_EXPORT(char *) ap_ht_time(pool *p, time_t t, const char *fmt, int gmt); API_EXPORT(char *) ap_gm_timestr_822(pool *p, time_t t); @@ -983,8 +1001,12 @@ void os2pathname(char *path); #endif +API_EXPORT(int) ap_regexec(const regex_t *preg, const char *string, + size_t nmatch, regmatch_t pmatch[], int eflags); +API_EXPORT(size_t) ap_regerror(int errcode, const regex_t *preg, + char *errbuf, size_t errbuf_size); API_EXPORT(char *) ap_pregsub(pool *p, const char *input, const char *source, - size_t nmatch, regmatch_t pmatch[]); + size_t nmatch, regmatch_t pmatch[]); API_EXPORT(void) ap_content_type_tolower(char *); API_EXPORT(void) ap_str_tolower(char *); 1.8 +4 -0 apache-apr/pthreads/src/include/scoreboard.h Index: scoreboard.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/scoreboard.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -u -r1.7 -r1.8 --- scoreboard.h 1999/04/09 04:10:35 1.7 +++ scoreboard.h 1999/06/10 06:25:56 1.8 @@ -188,6 +188,10 @@ } scoreboard; #define SCOREBOARD_SIZE sizeof(scoreboard) +#ifdef TPF +#define SCOREBOARD_NAME "SCOREBRD" +#define SCOREBOARD_FRAMES SCOREBOARD_SIZE/4095 + 1 +#endif API_EXPORT(int) ap_exists_scoreboard_image(void); void reinit_scoareboard(pool *p); 1.3 +4 -1 apache-apr/pthreads/src/include/util_md5.h Index: util_md5.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/include/util_md5.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- util_md5.h 1999/02/07 06:29:23 1.2 +++ util_md5.h 1999/06/10 06:25:56 1.3 @@ -67,11 +67,14 @@ API_EXPORT(char *) ap_md5(pool *a, const unsigned char *string); API_EXPORT(char *) ap_md5_binary(pool *a, const unsigned char *buf, int len); API_EXPORT(char *) ap_md5contextTo64(pool *p, AP_MD5_CTX * context); +#ifdef CHARSET_EBCDIC +API_EXPORT(char *) ap_md5digest(pool *p, FILE *infile, int convert); +#else API_EXPORT(char *) ap_md5digest(pool *p, APRFile infile); +#endif /* CHARSET_EBCDIC */ #ifdef __cplusplus } #endif #endif /* !APACHE_UTIL_MD5_H */ - 1.1 apache-apr/pthreads/src/lib/.cvsignore Index: .cvsignore =================================================================== Makefile 1.1 apache-apr/pthreads/src/lib/expat-lite/.cvsignore Index: .cvsignore =================================================================== Makefile 1.1 apache-apr/pthreads/src/lib/expat-lite/CHANGES Index: CHANGES =================================================================== === PURPOSE === This file documents the changes made by the Apache Group to James Clark's Expat parser. The original Expat distribution can be found at http://www.jclark.com/xml/expat.html. === SUBSET INFORMATION === Apache does not choose (or need) to use the entire Expat parser distribution. The subset that Apache will use will be referred to as "expat-lite". In particular, this directory contains the files from the following Expat distribution subdirectories: expat/xmltok/* expat/xmlparse/* We also retain expat/expat.html for attribution to James Clark and licensing information. In addition, we remove expat/xmltok/dllmain.c from our version since we statically link expat-lite into the executable (rather than building a DLL on the Win32 platform). The *.dsp files are also removed, since we place those elsewhere in the Apache source distribution and they will have a very different structure. Makefile.tmpl has been created from scratch to provide build instructions to the Apache build system. This file (CHANGES) has been added to document changes from the original Expat distribution. === CHANGES TO ORIGINAL === There have been no changes made to any Expat file at this point in time (May 31, 1999). The files, in their original state from the Expat distribution, have been tagged within CVS with the "EXPAT_1_1" tag. That tag may be used as a reference for changes made by the Apache Group. 1.1 apache-apr/pthreads/src/lib/expat-lite/Makefile.tmpl Index: Makefile.tmpl =================================================================== # # default definition of these two. dunno how to get it prepended when the # Makefile is built, so we do it manually # CFLAGS=$(OPTIM) $(CFLAGS1) $(EXTRA_CFLAGS) INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES) # If you know what your system's byte order is, define BYTE_ORDER: # use -DBYTE_ORDER=12 for little-endian byte order; # use -DBYTE_ORDER=21 for big-endian (network) byte order. #CFLAGS=-O2 OBJS=xmltok.o xmlrole.o xmlparse.o hashtable.o all lib: libexpat.a libexpat.a: $(OBJS) rm -f libexpat.a ar cr libexpat.a $(OBJS) $(RANLIB) libexpat.a clean: rm -f $(OBJS) libexpat.a distclean: clean -rm -f Makefile .SUFFIXES: .o .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< 1.1 apache-apr/pthreads/src/lib/expat-lite/asciitab.h Index: asciitab.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, /* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML, /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, 1.1 apache-apr/pthreads/src/lib/expat-lite/expat.html Index: expat.html =================================================================== <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <HTML> <TITLE>expat</TITLE> <BODY> <H1>expat - XML Parser Toolkit</H1> <H3>Version 1.1</H3> <P>Copyright (c) 1998, 1999 James Clark. Expat is subject to the <A HREF="http://www.mozilla.org/NPL/NPL-1_1Final.html">Mozilla Public License Version 1.1</A>. Alternatively you may use expat under the <A href="http://www.gnu.org/copyleft/gpl.html">GNU General Public License</A> instead. Please contact me if you wish to negotiate an alternative license.</P> <P>Expat is an <A HREF="http://www.w3.org/TR/1998/REC-xml-19980210">XML 1.0</A> parser written in C. It aims to be fully conforming. It is currently not a validating XML processor. The current production version of expat can be downloaded from <A href = "ftp://ftp.jclark.com/pub/xml/expat.zip" >ftp://ftp.jclark.com/pub/xml/expat.zip</A>.</P> <P>The directory <SAMP>xmltok</SAMP> contains a low-level library for tokenizing XML. The interface is documented in <SAMP>xmltok/xmltok.h</SAMP>.</P> <P>The directory <SAMP>xmlparse</SAMP> contains an XML parser library which is built on top of the <SAMP>xmltok</SAMP> library. The interface is documented in <SAMP>xmlparse/xmlparse.h</SAMP>. The directory <SAMP>sample</SAMP> contains a simple example program using this interface; <SAMP>sample/build.bat</SAMP> is a batch file to build the example using Visual C++.</P> <P>The directory <SAMP>xmlwf</SAMP> contains the <SAMP>xmlwf</SAMP> application, which uses the <SAMP>xmlparse</SAMP> library. The arguments to <SAMP>xmlwf</SAMP> are one or more files which are each to be checked for well-formedness. An option <SAMP>-d <VAR>dir</VAR></SAMP> can be specified; for each well-formed input file the corresponding <A href="http://www.jclark.com/xml/canonxml.html">canonical XML</A> will be written to <SAMP>dir/<VAR>f</VAR></SAMP>, where <SAMP><VAR>f</VAR></SAMP> is the filename (without any path) of the input file. A <CODE>-x</CODE> option will cause references to external general entities to be processed. A <CODE>-s</CODE> option will make documents that are not standalone cause an error (a document is considered standalone if either it is intrinsically standalone because it has no external subset and no references to parameter entities in the internal subset or it is declared as standalone in the XML declaration).</P> <P>The <SAMP>bin</SAMP> directory contains Win32 executables. The <SAMP>lib</SAMP> directory contains Win32 import libraries.</P> <P>Answers to some frequently asked questions about expat can be found in the <A HREF="http://www.jclark.com/xml/expatfaq.html">expat FAQ</A>.</P> <P></P> <ADDRESS> <A HREF="mailto:[EMAIL PROTECTED]">James Clark</A> </ADDRESS> </BODY> </HTML> 1.1 apache-apr/pthreads/src/lib/expat-lite/hashtable.c Index: hashtable.c =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in csompliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #include "xmldef.h" #ifdef XML_UNICODE_WCHAR_T #ifndef XML_UNICODE #define XML_UNICODE #endif #endif #include "hashtable.h" #define INIT_SIZE 64 static int keyeq(KEY s1, KEY s2) { for (; *s1 == *s2; s1++, s2++) if (*s1 == 0) return 1; return 0; } static unsigned long hash(KEY s) { unsigned long h = 0; while (*s) h = (h << 5) + h + (unsigned char)*s++; return h; } NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize) { size_t i; if (table->size == 0) { if (!createSize) return 0; table->v = calloc(INIT_SIZE, sizeof(NAMED *)); if (!table->v) return 0; table->size = INIT_SIZE; table->usedLim = INIT_SIZE / 2; i = hash(name) & (table->size - 1); } else { unsigned long h = hash(name); for (i = h & (table->size - 1); table->v[i]; i == 0 ? i = table->size - 1 : --i) { if (keyeq(name, table->v[i]->name)) return table->v[i]; } if (!createSize) return 0; if (table->used == table->usedLim) { /* check for overflow */ size_t newSize = table->size * 2; NAMED **newV = calloc(newSize, sizeof(NAMED *)); if (!newV) return 0; for (i = 0; i < table->size; i++) if (table->v[i]) { size_t j; for (j = hash(table->v[i]->name) & (newSize - 1); newV[j]; j == 0 ? j = newSize - 1 : --j) ; newV[j] = table->v[i]; } free(table->v); table->v = newV; table->size = newSize; table->usedLim = newSize/2; for (i = h & (table->size - 1); table->v[i]; i == 0 ? i = table->size - 1 : --i) ; } } table->v[i] = calloc(1, createSize); if (!table->v[i]) return 0; table->v[i]->name = name; (table->used)++; return table->v[i]; } void hashTableDestroy(HASH_TABLE *table) { size_t i; for (i = 0; i < table->size; i++) { NAMED *p = table->v[i]; if (p) free(p); } free(table->v); } void hashTableInit(HASH_TABLE *p) { p->size = 0; p->usedLim = 0; p->used = 0; p->v = 0; } void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table) { iter->p = table->v; iter->end = iter->p + table->size; } NAMED *hashTableIterNext(HASH_TABLE_ITER *iter) { while (iter->p != iter->end) { NAMED *tem = *(iter->p)++; if (tem) return tem; } return 0; } 1.1 apache-apr/pthreads/src/lib/expat-lite/hashtable.h Index: hashtable.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #include <stddef.h> #ifdef XML_UNICODE #ifdef XML_UNICODE_WCHAR_T typedef const wchar_t *KEY; #else /* not XML_UNICODE_WCHAR_T */ typedef const unsigned short *KEY; #endif /* not XML_UNICODE_WCHAR_T */ #else /* not XML_UNICODE */ typedef const char *KEY; #endif /* not XML_UNICODE */ typedef struct { KEY name; } NAMED; typedef struct { NAMED **v; size_t size; size_t used; size_t usedLim; } HASH_TABLE; NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize); void hashTableInit(HASH_TABLE *); void hashTableDestroy(HASH_TABLE *); typedef struct { NAMED **p; NAMED **end; } HASH_TABLE_ITER; void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *); NAMED *hashTableIterNext(HASH_TABLE_ITER *); 1.1 apache-apr/pthreads/src/lib/expat-lite/iasciitab.h Index: iasciitab.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ /* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */ /* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML, /* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML, /* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM, /* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS, /* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, /* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL, /* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT, /* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI, /* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST, /* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB, /* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT, /* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX, /* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT, /* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER, 1.1 apache-apr/pthreads/src/lib/expat-lite/latin1tab.h Index: latin1tab.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ /* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, /* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME, /* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER, /* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER, /* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER, /* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, /* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, 1.1 apache-apr/pthreads/src/lib/expat-lite/nametab.h Index: nametab.h =================================================================== static const unsigned namingBitmap[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF, 0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, 0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF, 0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000, 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060, 0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003, 0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003, 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000, 0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001, 0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003, 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000, 0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003, 0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003, 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000, 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF, 0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB, 0x40000000, 0xF580C900, 0x00000007, 0x02010800, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF, 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF, 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF, 0x00000000, 0x00004C40, 0x00000000, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF, 0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF, 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000, 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE, 0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF, 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003, 0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD, 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF, 0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF, 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE, 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF, 0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF, 0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF, 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF, 0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF, 0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0, 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1, 0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3, 0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80, 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3, 0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000, 0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000, 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF, 0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002, 0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF, }; static const unsigned char nmstrtPages[] = { 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const unsigned char namePages[] = { 0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13, 0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; 1.1 apache-apr/pthreads/src/lib/expat-lite/utf8tab.h Index: utf8tab.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ /* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL, /* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2, /* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3, /* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4, /* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML, /* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML, /* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM, 1.1 apache-apr/pthreads/src/lib/expat-lite/xmldef.h Index: xmldef.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #include <string.h> #ifdef XML_WINLIB #define WIN32_LEAN_AND_MEAN #define STRICT #include <windows.h> #define malloc(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define calloc(x, y) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)*(y)) #define free(x) HeapFree(GetProcessHeap(), 0, (x)) #define realloc(x, y) HeapReAlloc(GetProcessHeap(), 0, x, y) #define abort() /* as nothing */ #else /* not XML_WINLIB */ #include <stdlib.h> #endif /* not XML_WINLIB */ /* This file can be used for any definitions needed in particular environments. */ #ifdef MOZILLA #include "nspr.h" #define malloc(x) PR_Malloc(x) #define realloc(x, y) PR_Realloc((x), (y)) #define calloc(x, y) PR_Calloc((x),(y)) #define free(x) PR_Free(x) #define int int32 #endif /* MOZILLA */ 1.1 apache-apr/pthreads/src/lib/expat-lite/xmlparse.c Index: xmlparse.c =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #include "xmldef.h" #include "xmlparse.h" #ifdef XML_UNICODE #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX #define XmlConvert XmlUtf16Convert #define XmlGetInternalEncoding XmlGetUtf16InternalEncoding #define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS #define XmlEncode XmlUtf16Encode #define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1)) typedef unsigned short ICHAR; #else #define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX #define XmlConvert XmlUtf8Convert #define XmlGetInternalEncoding XmlGetUtf8InternalEncoding #define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS #define XmlEncode XmlUtf8Encode #define MUST_CONVERT(enc, s) (!(enc)->isUtf8) typedef char ICHAR; #endif #ifndef XML_NS #define XmlInitEncodingNS XmlInitEncoding #define XmlInitUnknownEncodingNS XmlInitUnknownEncoding #undef XmlGetInternalEncodingNS #define XmlGetInternalEncodingNS XmlGetInternalEncoding #define XmlParseXmlDeclNS XmlParseXmlDecl #endif #ifdef XML_UNICODE_WCHAR_T #define XML_T(x) L ## x #else #define XML_T(x) x #endif /* Round up n to be a multiple of sz, where sz is a power of 2. */ #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) #include "xmltok.h" #include "xmlrole.h" #include "hashtable.h" #define INIT_TAG_BUF_SIZE 32 /* must be a multiple of sizeof(XML_Char) */ #define INIT_DATA_BUF_SIZE 1024 #define INIT_ATTS_SIZE 16 #define INIT_BLOCK_SIZE 1024 #define INIT_BUFFER_SIZE 1024 #define EXPAND_SPARE 24 typedef struct binding { struct prefix *prefix; struct binding *nextTagBinding; struct binding *prevPrefixBinding; const struct attribute_id *attId; XML_Char *uri; int uriLen; int uriAlloc; } BINDING; typedef struct prefix { const XML_Char *name; BINDING *binding; } PREFIX; typedef struct { const XML_Char *str; const XML_Char *localPart; int uriLen; } TAG_NAME; typedef struct tag { struct tag *parent; const char *rawName; int rawNameLength; TAG_NAME name; char *buf; char *bufEnd; BINDING *bindings; } TAG; typedef struct { const XML_Char *name; const XML_Char *textPtr; int textLen; const XML_Char *systemId; const XML_Char *base; const XML_Char *publicId; const XML_Char *notation; char open; } ENTITY; typedef struct block { struct block *next; int size; XML_Char s[1]; } BLOCK; typedef struct { BLOCK *blocks; BLOCK *freeBlocks; const XML_Char *end; XML_Char *ptr; XML_Char *start; } STRING_POOL; /* The XML_Char before the name is used to determine whether an attribute has been specified. */ typedef struct attribute_id { XML_Char *name; PREFIX *prefix; char maybeTokenized; char xmlns; } ATTRIBUTE_ID; typedef struct { const ATTRIBUTE_ID *id; char isCdata; const XML_Char *value; } DEFAULT_ATTRIBUTE; typedef struct { const XML_Char *name; PREFIX *prefix; int nDefaultAtts; int allocDefaultAtts; DEFAULT_ATTRIBUTE *defaultAtts; } ELEMENT_TYPE; typedef struct { HASH_TABLE generalEntities; HASH_TABLE elementTypes; HASH_TABLE attributeIds; HASH_TABLE prefixes; STRING_POOL pool; int complete; int standalone; const XML_Char *base; PREFIX defaultPrefix; } DTD; typedef struct open_internal_entity { const char *internalEventPtr; const char *internalEventEndPtr; struct open_internal_entity *next; ENTITY *entity; } OPEN_INTERNAL_ENTITY; typedef enum XML_Error Processor(XML_Parser parser, const char *start, const char *end, const char **endPtr); static Processor prologProcessor; static Processor prologInitProcessor; static Processor contentProcessor; static Processor cdataSectionProcessor; static Processor epilogProcessor; #if 0 static Processor errorProcessor; #endif static Processor externalEntityInitProcessor; static Processor externalEntityInitProcessor2; static Processor externalEntityInitProcessor3; static Processor externalEntityContentProcessor; static enum XML_Error handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName); static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *); static enum XML_Error initializeEncoding(XML_Parser parser); static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *start, const char *end, const char **endPtr); static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr); static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr); static int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr); static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue); static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *, STRING_POOL *); static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *, STRING_POOL *); static ATTRIBUTE_ID * getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *); static enum XML_Error storeEntityValue(XML_Parser parser, const char *start, const char *end); static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static int reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static void reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end); static const XML_Char *getContext(XML_Parser parser); static int setContext(XML_Parser parser, const XML_Char *context); static void normalizePublicId(XML_Char *s); static int dtdInit(DTD *); static void dtdDestroy(DTD *); static int dtdCopy(DTD *newDtd, const DTD *oldDtd); static void poolInit(STRING_POOL *); static void poolClear(STRING_POOL *); static void poolDestroy(STRING_POOL *); static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end); static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end); static int poolGrow(STRING_POOL *pool); static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s); static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n); #define poolStart(pool) ((pool)->start) #define poolEnd(pool) ((pool)->ptr) #define poolLength(pool) ((pool)->ptr - (pool)->start) #define poolChop(pool) ((void)--(pool->ptr)) #define poolLastChar(pool) (((pool)->ptr)[-1]) #define poolDiscard(pool) ((pool)->ptr = (pool)->start) #define poolFinish(pool) ((pool)->start = (pool)->ptr) #define poolAppendChar(pool, c) \ (((pool)->ptr == (pool)->end && !poolGrow(pool)) \ ? 0 \ : ((*((pool)->ptr)++ = c), 1)) typedef struct { /* The first member must be userData so that the XML_GetUserData macro works. */ void *m_userData; void *m_handlerArg; char *m_buffer; /* first character to be parsed */ const char *m_bufferPtr; /* past last character to be parsed */ char *m_bufferEnd; /* allocated end of buffer */ const char *m_bufferLim; long m_parseEndByteIndex; const char *m_parseEndPtr; XML_Char *m_dataBuf; XML_Char *m_dataBufEnd; XML_StartElementHandler m_startElementHandler; XML_EndElementHandler m_endElementHandler; XML_CharacterDataHandler m_characterDataHandler; XML_ProcessingInstructionHandler m_processingInstructionHandler; XML_CommentHandler m_commentHandler; XML_StartCdataSectionHandler m_startCdataSectionHandler; XML_EndCdataSectionHandler m_endCdataSectionHandler; XML_DefaultHandler m_defaultHandler; XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler; XML_NotationDeclHandler m_notationDeclHandler; XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler; XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler; XML_NotStandaloneHandler m_notStandaloneHandler; XML_ExternalEntityRefHandler m_externalEntityRefHandler; void *m_externalEntityRefHandlerArg; XML_UnknownEncodingHandler m_unknownEncodingHandler; const ENCODING *m_encoding; INIT_ENCODING m_initEncoding; const XML_Char *m_protocolEncodingName; int m_ns; void *m_unknownEncodingMem; void *m_unknownEncodingData; void *m_unknownEncodingHandlerData; void (*m_unknownEncodingRelease)(void *); PROLOG_STATE m_prologState; Processor *m_processor; enum XML_Error m_errorCode; const char *m_eventPtr; const char *m_eventEndPtr; const char *m_positionPtr; OPEN_INTERNAL_ENTITY *m_openInternalEntities; int m_defaultExpandInternalEntities; int m_tagLevel; ENTITY *m_declEntity; const XML_Char *m_declNotationName; const XML_Char *m_declNotationPublicId; ELEMENT_TYPE *m_declElementType; ATTRIBUTE_ID *m_declAttributeId; char m_declAttributeIsCdata; DTD m_dtd; TAG *m_tagStack; TAG *m_freeTagList; BINDING *m_inheritedBindings; BINDING *m_freeBindingList; int m_attsSize; int m_nSpecifiedAtts; ATTRIBUTE *m_atts; POSITION m_position; STRING_POOL m_tempPool; STRING_POOL m_temp2Pool; char *m_groupConnector; unsigned m_groupSize; int m_hadExternalDoctype; XML_Char m_namespaceSeparator; } Parser; #define userData (((Parser *)parser)->m_userData) #define handlerArg (((Parser *)parser)->m_handlerArg) #define startElementHandler (((Parser *)parser)->m_startElementHandler) #define endElementHandler (((Parser *)parser)->m_endElementHandler) #define characterDataHandler (((Parser *)parser)->m_characterDataHandler) #define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler) #define commentHandler (((Parser *)parser)->m_commentHandler) #define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler) #define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler) #define defaultHandler (((Parser *)parser)->m_defaultHandler) #define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler) #define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler) #define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler) #define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler) #define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler) #define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler) #define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg) #define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler) #define encoding (((Parser *)parser)->m_encoding) #define initEncoding (((Parser *)parser)->m_initEncoding) #define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem) #define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData) #define unknownEncodingHandlerData \ (((Parser *)parser)->m_unknownEncodingHandlerData) #define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease) #define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName) #define ns (((Parser *)parser)->m_ns) #define prologState (((Parser *)parser)->m_prologState) #define processor (((Parser *)parser)->m_processor) #define errorCode (((Parser *)parser)->m_errorCode) #define eventPtr (((Parser *)parser)->m_eventPtr) #define eventEndPtr (((Parser *)parser)->m_eventEndPtr) #define positionPtr (((Parser *)parser)->m_positionPtr) #define position (((Parser *)parser)->m_position) #define openInternalEntities (((Parser *)parser)->m_openInternalEntities) #define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities) #define tagLevel (((Parser *)parser)->m_tagLevel) #define buffer (((Parser *)parser)->m_buffer) #define bufferPtr (((Parser *)parser)->m_bufferPtr) #define bufferEnd (((Parser *)parser)->m_bufferEnd) #define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex) #define parseEndPtr (((Parser *)parser)->m_parseEndPtr) #define bufferLim (((Parser *)parser)->m_bufferLim) #define dataBuf (((Parser *)parser)->m_dataBuf) #define dataBufEnd (((Parser *)parser)->m_dataBufEnd) #define dtd (((Parser *)parser)->m_dtd) #define declEntity (((Parser *)parser)->m_declEntity) #define declNotationName (((Parser *)parser)->m_declNotationName) #define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId) #define declElementType (((Parser *)parser)->m_declElementType) #define declAttributeId (((Parser *)parser)->m_declAttributeId) #define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata) #define freeTagList (((Parser *)parser)->m_freeTagList) #define freeBindingList (((Parser *)parser)->m_freeBindingList) #define inheritedBindings (((Parser *)parser)->m_inheritedBindings) #define tagStack (((Parser *)parser)->m_tagStack) #define atts (((Parser *)parser)->m_atts) #define attsSize (((Parser *)parser)->m_attsSize) #define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts) #define tempPool (((Parser *)parser)->m_tempPool) #define temp2Pool (((Parser *)parser)->m_temp2Pool) #define groupConnector (((Parser *)parser)->m_groupConnector) #define groupSize (((Parser *)parser)->m_groupSize) #define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype) #define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator) #ifdef _MSC_VER #ifdef _DEBUG Parser *asParser(XML_Parser parser) { return parser; } #endif #endif XML_Parser XML_ParserCreate(const XML_Char *encodingName) { XML_Parser parser = malloc(sizeof(Parser)); if (!parser) return parser; processor = prologInitProcessor; XmlPrologStateInit(&prologState); userData = 0; handlerArg = 0; startElementHandler = 0; endElementHandler = 0; characterDataHandler = 0; processingInstructionHandler = 0; commentHandler = 0; startCdataSectionHandler = 0; endCdataSectionHandler = 0; defaultHandler = 0; unparsedEntityDeclHandler = 0; notationDeclHandler = 0; startNamespaceDeclHandler = 0; endNamespaceDeclHandler = 0; notStandaloneHandler = 0; externalEntityRefHandler = 0; externalEntityRefHandlerArg = parser; unknownEncodingHandler = 0; buffer = 0; bufferPtr = 0; bufferEnd = 0; parseEndByteIndex = 0; parseEndPtr = 0; bufferLim = 0; declElementType = 0; declAttributeId = 0; declEntity = 0; declNotationName = 0; declNotationPublicId = 0; memset(&position, 0, sizeof(POSITION)); errorCode = XML_ERROR_NONE; eventPtr = 0; eventEndPtr = 0; positionPtr = 0; openInternalEntities = 0; tagLevel = 0; tagStack = 0; freeTagList = 0; freeBindingList = 0; inheritedBindings = 0; attsSize = INIT_ATTS_SIZE; atts = malloc(attsSize * sizeof(ATTRIBUTE)); nSpecifiedAtts = 0; dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char)); groupSize = 0; groupConnector = 0; hadExternalDoctype = 0; unknownEncodingMem = 0; unknownEncodingRelease = 0; unknownEncodingData = 0; unknownEncodingHandlerData = 0; namespaceSeparator = '!'; ns = 0; poolInit(&tempPool); poolInit(&temp2Pool); protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0; if (!dtdInit(&dtd) || !atts || !dataBuf || (encodingName && !protocolEncodingName)) { XML_ParserFree(parser); return 0; } dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE; XmlInitEncoding(&initEncoding, &encoding, 0); return parser; } XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep) { static const XML_Char implicitContext[] = { XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='), XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'), XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'), XML_T('.'), XML_T('w'), XML_T('3'), XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'), XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'), XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'), XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'), XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'), XML_T('\0') }; XML_Parser parser = XML_ParserCreate(encodingName); if (parser) { XmlInitEncodingNS(&initEncoding, &encoding, 0); ns = 1; namespaceSeparator = nsSep; } if (!setContext(parser, implicitContext)) { XML_ParserFree(parser); return 0; } return parser; } int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { if (!encodingName) protocolEncodingName = 0; else { protocolEncodingName = poolCopyString(&tempPool, encodingName); if (!protocolEncodingName) return 0; } return 1; } XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context, const XML_Char *encodingName) { XML_Parser parser = oldParser; DTD *oldDtd = &dtd; XML_StartElementHandler oldStartElementHandler = startElementHandler; XML_EndElementHandler oldEndElementHandler = endElementHandler; XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler; XML_CommentHandler oldCommentHandler = commentHandler; XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler; XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler; XML_DefaultHandler oldDefaultHandler = defaultHandler; XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler; XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler; XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler; XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler; void *oldUserData = userData; void *oldHandlerArg = handlerArg; int oldDefaultExpandInternalEntities = defaultExpandInternalEntities; void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; parser = (ns ? XML_ParserCreateNS(encodingName, namespaceSeparator) : XML_ParserCreate(encodingName)); if (!parser) return 0; startElementHandler = oldStartElementHandler; endElementHandler = oldEndElementHandler; characterDataHandler = oldCharacterDataHandler; processingInstructionHandler = oldProcessingInstructionHandler; commentHandler = oldCommentHandler; startCdataSectionHandler = oldStartCdataSectionHandler; endCdataSectionHandler = oldEndCdataSectionHandler; defaultHandler = oldDefaultHandler; startNamespaceDeclHandler = oldStartNamespaceDeclHandler; endNamespaceDeclHandler = oldEndNamespaceDeclHandler; notStandaloneHandler = oldNotStandaloneHandler; externalEntityRefHandler = oldExternalEntityRefHandler; unknownEncodingHandler = oldUnknownEncodingHandler; userData = oldUserData; if (oldUserData == oldHandlerArg) handlerArg = userData; else handlerArg = parser; if (oldExternalEntityRefHandlerArg != oldParser) externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg; defaultExpandInternalEntities = oldDefaultExpandInternalEntities; if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) { XML_ParserFree(parser); return 0; } processor = externalEntityInitProcessor; return parser; } static void destroyBindings(BINDING *bindings) { for (;;) { BINDING *b = bindings; if (!b) break; bindings = b->nextTagBinding; free(b->uri); free(b); } } void XML_ParserFree(XML_Parser parser) { for (;;) { TAG *p; if (tagStack == 0) { if (freeTagList == 0) break; tagStack = freeTagList; freeTagList = 0; } p = tagStack; tagStack = tagStack->parent; free(p->buf); destroyBindings(p->bindings); free(p); } destroyBindings(freeBindingList); destroyBindings(inheritedBindings); poolDestroy(&tempPool); poolDestroy(&temp2Pool); dtdDestroy(&dtd); free((void *)atts); free(groupConnector); free(buffer); free(dataBuf); free(unknownEncodingMem); if (unknownEncodingRelease) unknownEncodingRelease(unknownEncodingData); free(parser); } void XML_UseParserAsHandlerArg(XML_Parser parser) { handlerArg = parser; } void XML_SetUserData(XML_Parser parser, void *p) { if (handlerArg == userData) handlerArg = userData = p; else userData = p; } int XML_SetBase(XML_Parser parser, const XML_Char *p) { if (p) { p = poolCopyString(&dtd.pool, p); if (!p) return 0; dtd.base = p; } else dtd.base = 0; return 1; } const XML_Char *XML_GetBase(XML_Parser parser) { return dtd.base; } int XML_GetSpecifiedAttributeCount(XML_Parser parser) { return nSpecifiedAtts; } void XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) { startElementHandler = start; endElementHandler = end; } void XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler) { characterDataHandler = handler; } void XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler) { processingInstructionHandler = handler; } void XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { commentHandler = handler; } void XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end) { startCdataSectionHandler = start; endCdataSectionHandler = end; } void XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { defaultHandler = handler; defaultExpandInternalEntities = 0; } void XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { defaultHandler = handler; defaultExpandInternalEntities = 1; } void XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler) { unparsedEntityDeclHandler = handler; } void XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { notationDeclHandler = handler; } void XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end) { startNamespaceDeclHandler = start; endNamespaceDeclHandler = end; } void XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler) { notStandaloneHandler = handler; } void XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler) { externalEntityRefHandler = handler; } void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { if (arg) externalEntityRefHandlerArg = arg; else externalEntityRefHandlerArg = parser; } void XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *data) { unknownEncodingHandler = handler; unknownEncodingHandlerData = data; } int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { if (len == 0) { if (!isFinal) return 1; positionPtr = bufferPtr; errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0); if (errorCode == XML_ERROR_NONE) return 1; eventEndPtr = eventPtr; return 0; } else if (bufferPtr == bufferEnd) { const char *end; int nLeftOver; parseEndByteIndex += len; positionPtr = s; if (isFinal) { errorCode = processor(parser, s, parseEndPtr = s + len, 0); if (errorCode == XML_ERROR_NONE) return 1; eventEndPtr = eventPtr; return 0; } errorCode = processor(parser, s, parseEndPtr = s + len, &end); if (errorCode != XML_ERROR_NONE) { eventEndPtr = eventPtr; return 0; } XmlUpdatePosition(encoding, positionPtr, end, &position); nLeftOver = s + len - end; if (nLeftOver) { if (buffer == 0 || nLeftOver > bufferLim - buffer) { /* FIXME avoid integer overflow */ buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2); if (!buffer) { errorCode = XML_ERROR_NO_MEMORY; eventPtr = eventEndPtr = 0; return 0; } bufferLim = buffer + len * 2; } memcpy(buffer, end, nLeftOver); bufferPtr = buffer; bufferEnd = buffer + nLeftOver; } return 1; } else { memcpy(XML_GetBuffer(parser, len), s, len); return XML_ParseBuffer(parser, len, isFinal); } } int XML_ParseBuffer(XML_Parser parser, int len, int isFinal) { const char *start = bufferPtr; positionPtr = start; bufferEnd += len; parseEndByteIndex += len; errorCode = processor(parser, start, parseEndPtr = bufferEnd, isFinal ? (const char **)0 : &bufferPtr); if (errorCode == XML_ERROR_NONE) { if (!isFinal) XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position); return 1; } else { eventEndPtr = eventPtr; return 0; } } void *XML_GetBuffer(XML_Parser parser, int len) { if (len > bufferLim - bufferEnd) { /* FIXME avoid integer overflow */ int neededSize = len + (bufferEnd - bufferPtr); if (neededSize <= bufferLim - buffer) { memmove(buffer, bufferPtr, bufferEnd - bufferPtr); bufferEnd = buffer + (bufferEnd - bufferPtr); bufferPtr = buffer; } else { char *newBuf; int bufferSize = bufferLim - bufferPtr; if (bufferSize == 0) bufferSize = INIT_BUFFER_SIZE; do { bufferSize *= 2; } while (bufferSize < neededSize); newBuf = malloc(bufferSize); if (newBuf == 0) { errorCode = XML_ERROR_NO_MEMORY; return 0; } bufferLim = newBuf + bufferSize; if (bufferPtr) { memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr); free(buffer); } bufferEnd = newBuf + (bufferEnd - bufferPtr); bufferPtr = buffer = newBuf; } } return bufferEnd; } enum XML_Error XML_GetErrorCode(XML_Parser parser) { return errorCode; } long XML_GetCurrentByteIndex(XML_Parser parser) { if (eventPtr) return parseEndByteIndex - (parseEndPtr - eventPtr); return -1; } int XML_GetCurrentByteCount(XML_Parser parser) { if (eventEndPtr && eventPtr) return eventEndPtr - eventPtr; return 0; } int XML_GetCurrentLineNumber(XML_Parser parser) { if (eventPtr) { XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); positionPtr = eventPtr; } return position.lineNumber + 1; } int XML_GetCurrentColumnNumber(XML_Parser parser) { if (eventPtr) { XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); positionPtr = eventPtr; } return position.columnNumber; } void XML_DefaultCurrent(XML_Parser parser) { if (defaultHandler) { if (openInternalEntities) reportDefault(parser, ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(), openInternalEntities->internalEventPtr, openInternalEntities->internalEventEndPtr); else reportDefault(parser, encoding, eventPtr, eventEndPtr); } } const XML_LChar *XML_ErrorString(int code) { static const XML_LChar *message[] = { 0, XML_T("out of memory"), XML_T("syntax error"), XML_T("no element found"), XML_T("not well-formed"), XML_T("unclosed token"), XML_T("unclosed token"), XML_T("mismatched tag"), XML_T("duplicate attribute"), XML_T("junk after document element"), XML_T("illegal parameter entity reference"), XML_T("undefined entity"), XML_T("recursive entity reference"), XML_T("asynchronous entity"), XML_T("reference to invalid character number"), XML_T("reference to binary entity"), XML_T("reference to external entity in attribute"), XML_T("xml processing instruction not at start of external entity"), XML_T("unknown encoding"), XML_T("encoding specified in XML declaration is incorrect"), XML_T("unclosed CDATA section"), XML_T("error in processing external entity reference"), XML_T("document is not standalone") }; if (code > 0 && code < sizeof(message)/sizeof(message[0])) return message[code]; return 0; } static enum XML_Error contentProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { return doContent(parser, 0, encoding, start, end, endPtr); } static enum XML_Error externalEntityInitProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; processor = externalEntityInitProcessor2; return externalEntityInitProcessor2(parser, start, end, endPtr); } static enum XML_Error externalEntityInitProcessor2(XML_Parser parser, const char *start, const char *end, const char **endPtr) { const char *next; int tok = XmlContentTok(encoding, start, end, &next); switch (tok) { case XML_TOK_BOM: start = next; break; case XML_TOK_PARTIAL: if (endPtr) { *endPtr = start; return XML_ERROR_NONE; } eventPtr = start; return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (endPtr) { *endPtr = start; return XML_ERROR_NONE; } eventPtr = start; return XML_ERROR_PARTIAL_CHAR; } processor = externalEntityInitProcessor3; return externalEntityInitProcessor3(parser, start, end, endPtr); } static enum XML_Error externalEntityInitProcessor3(XML_Parser parser, const char *start, const char *end, const char **endPtr) { const char *next; int tok = XmlContentTok(encoding, start, end, &next); switch (tok) { case XML_TOK_XML_DECL: { enum XML_Error result = processXmlDecl(parser, 1, start, next); if (result != XML_ERROR_NONE) return result; start = next; } break; case XML_TOK_PARTIAL: if (endPtr) { *endPtr = start; return XML_ERROR_NONE; } eventPtr = start; return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (endPtr) { *endPtr = start; return XML_ERROR_NONE; } eventPtr = start; return XML_ERROR_PARTIAL_CHAR; } processor = externalEntityContentProcessor; tagLevel = 1; return doContent(parser, 1, encoding, start, end, endPtr); } static enum XML_Error externalEntityContentProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { return doContent(parser, 1, encoding, start, end, endPtr); } static enum XML_Error doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc, const char *s, const char *end, const char **nextPtr) { const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); const char **eventPP; const char **eventEndPP; if (enc == encoding) { eventPP = &eventPtr; eventEndPP = &eventEndPtr; } else { eventPP = &(openInternalEntities->internalEventPtr); eventEndPP = &(openInternalEntities->internalEventEndPtr); } *eventPP = s; for (;;) { const char *next = s; /* XmlContentTok doesn't always set the last arg */ int tok = XmlContentTok(enc, s, end, &next); *eventEndPP = next; switch (tok) { case XML_TOK_TRAILING_CR: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } *eventEndPP = end; if (characterDataHandler) { XML_Char c = 0xA; characterDataHandler(handlerArg, &c, 1); } else if (defaultHandler) reportDefault(parser, enc, s, end); if (startTagLevel == 0) return XML_ERROR_NO_ELEMENTS; if (tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; return XML_ERROR_NONE; case XML_TOK_NONE: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } if (startTagLevel > 0) { if (tagLevel != startTagLevel) return XML_ERROR_ASYNC_ENTITY; return XML_ERROR_NONE; } return XML_ERROR_NO_ELEMENTS; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_ENTITY_REF: { const XML_Char *name; ENTITY *entity; XML_Char ch = XmlPredefinedEntityName(enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (ch) { if (characterDataHandler) characterDataHandler(handlerArg, &ch, 1); else if (defaultHandler) reportDefault(parser, enc, s, next); break; } name = poolStoreString(&dtd.pool, enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar); if (!name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0); poolDiscard(&dtd.pool); if (!entity) { if (dtd.complete || dtd.standalone) return XML_ERROR_UNDEFINED_ENTITY; if (defaultHandler) reportDefault(parser, enc, s, next); break; } if (entity->open) return XML_ERROR_RECURSIVE_ENTITY_REF; if (entity->notation) return XML_ERROR_BINARY_ENTITY_REF; if (entity) { if (entity->textPtr) { enum XML_Error result; OPEN_INTERNAL_ENTITY openEntity; if (defaultHandler && !defaultExpandInternalEntities) { reportDefault(parser, enc, s, next); break; } entity->open = 1; openEntity.next = openInternalEntities; openInternalEntities = &openEntity; openEntity.entity = entity; openEntity.internalEventPtr = 0; openEntity.internalEventEndPtr = 0; result = doContent(parser, tagLevel, internalEnc, (char *)entity->textPtr, (char *)(entity->textPtr + entity->textLen), 0); entity->open = 0; openInternalEntities = openEntity.next; if (result) return result; } else if (externalEntityRefHandler) { const XML_Char *context; entity->open = 1; context = getContext(parser); entity->open = 0; if (!context) return XML_ERROR_NO_MEMORY; if (!externalEntityRefHandler(externalEntityRefHandlerArg, context, dtd.base, entity->systemId, entity->publicId)) return XML_ERROR_EXTERNAL_ENTITY_HANDLING; poolDiscard(&tempPool); } else if (defaultHandler) reportDefault(parser, enc, s, next); } break; } case XML_TOK_START_TAG_WITH_ATTS: if (!startElementHandler) { enum XML_Error result = storeAtts(parser, enc, s, 0, 0); if (result) return result; } /* fall through */ case XML_TOK_START_TAG_NO_ATTS: { TAG *tag; if (freeTagList) { tag = freeTagList; freeTagList = freeTagList->parent; } else { tag = malloc(sizeof(TAG)); if (!tag) return XML_ERROR_NO_MEMORY; tag->buf = malloc(INIT_TAG_BUF_SIZE); if (!tag->buf) return XML_ERROR_NO_MEMORY; tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE; } tag->bindings = 0; tag->parent = tagStack; tagStack = tag; tag->name.localPart = 0; tag->rawName = s + enc->minBytesPerChar; tag->rawNameLength = XmlNameLength(enc, tag->rawName); if (nextPtr) { /* Need to guarantee that: tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */ if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) { int bufSize = tag->rawNameLength * 4; bufSize = ROUND_UP(bufSize, sizeof(XML_Char)); tag->buf = realloc(tag->buf, bufSize); if (!tag->buf) return XML_ERROR_NO_MEMORY; tag->bufEnd = tag->buf + bufSize; } memcpy(tag->buf, tag->rawName, tag->rawNameLength); tag->rawName = tag->buf; } ++tagLevel; if (startElementHandler) { enum XML_Error result; XML_Char *toPtr; for (;;) { const char *rawNameEnd = tag->rawName + tag->rawNameLength; const char *fromPtr = tag->rawName; int bufSize; if (nextPtr) toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char))); else toPtr = (XML_Char *)tag->buf; tag->name.str = toPtr; XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); if (fromPtr == rawNameEnd) break; bufSize = (tag->bufEnd - tag->buf) << 1; tag->buf = realloc(tag->buf, bufSize); if (!tag->buf) return XML_ERROR_NO_MEMORY; tag->bufEnd = tag->buf + bufSize; if (nextPtr) tag->rawName = tag->buf; } *toPtr = XML_T('\0'); result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings)); if (result) return result; startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts); poolClear(&tempPool); } else { tag->name.str = 0; if (defaultHandler) reportDefault(parser, enc, s, next); } break; } case XML_TOK_EMPTY_ELEMENT_WITH_ATTS: if (!startElementHandler) { enum XML_Error result = storeAtts(parser, enc, s, 0, 0); if (result) return result; } /* fall through */ case XML_TOK_EMPTY_ELEMENT_NO_ATTS: if (startElementHandler || endElementHandler) { const char *rawName = s + enc->minBytesPerChar; enum XML_Error result; BINDING *bindings = 0; TAG_NAME name; name.str = poolStoreString(&tempPool, enc, rawName, rawName + XmlNameLength(enc, rawName)); if (!name.str) return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); result = storeAtts(parser, enc, s, &name, &bindings); if (result) return result; poolFinish(&tempPool); if (startElementHandler) startElementHandler(handlerArg, name.str, (const XML_Char **)atts); if (endElementHandler) { if (startElementHandler) *eventPP = *eventEndPP; endElementHandler(handlerArg, name.str); } poolClear(&tempPool); while (bindings) { BINDING *b = bindings; if (endNamespaceDeclHandler) endNamespaceDeclHandler(handlerArg, b->prefix->name); bindings = bindings->nextTagBinding; b->nextTagBinding = freeBindingList; freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } } else if (defaultHandler) reportDefault(parser, enc, s, next); if (tagLevel == 0) return epilogProcessor(parser, next, end, nextPtr); break; case XML_TOK_END_TAG: if (tagLevel == startTagLevel) return XML_ERROR_ASYNC_ENTITY; else { int len; const char *rawName; TAG *tag = tagStack; tagStack = tag->parent; tag->parent = freeTagList; freeTagList = tag; rawName = s + enc->minBytesPerChar*2; len = XmlNameLength(enc, rawName); if (len != tag->rawNameLength || memcmp(tag->rawName, rawName, len) != 0) { *eventPP = rawName; return XML_ERROR_TAG_MISMATCH; } --tagLevel; if (endElementHandler && tag->name.str) { if (tag->name.localPart) { XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen; const XML_Char *from = tag->name.localPart; while ((*to++ = *from++) != 0) ; } endElementHandler(handlerArg, tag->name.str); } else if (defaultHandler) reportDefault(parser, enc, s, next); while (tag->bindings) { BINDING *b = tag->bindings; if (endNamespaceDeclHandler) endNamespaceDeclHandler(handlerArg, b->prefix->name); tag->bindings = tag->bindings->nextTagBinding; b->nextTagBinding = freeBindingList; freeBindingList = b; b->prefix->binding = b->prevPrefixBinding; } if (tagLevel == 0) return epilogProcessor(parser, next, end, nextPtr); } break; case XML_TOK_CHAR_REF: { int n = XmlCharRefNumber(enc, s); if (n < 0) return XML_ERROR_BAD_CHAR_REF; if (characterDataHandler) { XML_Char buf[XML_ENCODE_MAX]; characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf)); } else if (defaultHandler) reportDefault(parser, enc, s, next); } break; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; case XML_TOK_DATA_NEWLINE: if (characterDataHandler) { XML_Char c = 0xA; characterDataHandler(handlerArg, &c, 1); } else if (defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_CDATA_SECT_OPEN: { enum XML_Error result; if (startCdataSectionHandler) startCdataSectionHandler(handlerArg); #if 0 /* Suppose you doing a transformation on a document that involves changing only the character data. You set up a defaultHandler and a characterDataHandler. The defaultHandler simply copies characters through. The characterDataHandler does the transformation and writes the characters out escaping them as necessary. This case will fail to work if we leave out the following two lines (because & and < inside CDATA sections will be incorrectly escaped). However, now we have a start/endCdataSectionHandler, so it seems easier to let the user deal with this. */ else if (characterDataHandler) characterDataHandler(handlerArg, dataBuf, 0); #endif else if (defaultHandler) reportDefault(parser, enc, s, next); result = doCdataSection(parser, enc, &next, end, nextPtr); if (!next) { processor = cdataSectionProcessor; return result; } } break; case XML_TOK_TRAILING_RSQB: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } if (characterDataHandler) { if (MUST_CONVERT(enc, s)) { ICHAR *dataPtr = (ICHAR *)dataBuf; XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); } else characterDataHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s); } else if (defaultHandler) reportDefault(parser, enc, s, end); if (startTagLevel == 0) { *eventPP = end; return XML_ERROR_NO_ELEMENTS; } if (tagLevel != startTagLevel) { *eventPP = end; return XML_ERROR_ASYNC_ENTITY; } return XML_ERROR_NONE; case XML_TOK_DATA_CHARS: if (characterDataHandler) { if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)dataBuf; XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); *eventEndPP = s; characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); if (s == next) break; *eventPP = s; } } else characterDataHandler(handlerArg, (XML_Char *)s, (XML_Char *)next - (XML_Char *)s); } else if (defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_PI: if (!reportProcessingInstruction(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: if (!reportComment(parser, enc, s, next)) return XML_ERROR_NO_MEMORY; break; default: if (defaultHandler) reportDefault(parser, enc, s, next); break; } *eventPP = s = next; } /* not reached */ } /* If tagNamePtr is non-null, build a real list of attributes, otherwise just check the attributes for well-formedness. */ static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc, const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr) { ELEMENT_TYPE *elementType = 0; int nDefaultAtts = 0; const XML_Char **appAtts; int attIndex = 0; int i; int n; int nPrefixes = 0; BINDING *binding; const XML_Char *localPart; if (tagNamePtr) { elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0); if (!elementType) { tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str); if (!tagNamePtr->str) return XML_ERROR_NO_MEMORY; elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE)); if (!elementType) return XML_ERROR_NO_MEMORY; if (ns && !setElementTypePrefix(parser, elementType)) return XML_ERROR_NO_MEMORY; } nDefaultAtts = elementType->nDefaultAtts; } n = XmlGetAttributes(enc, s, attsSize, atts); if (n + nDefaultAtts > attsSize) { int oldAttsSize = attsSize; attsSize = n + nDefaultAtts + INIT_ATTS_SIZE; atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE)); if (!atts) return XML_ERROR_NO_MEMORY; if (n > oldAttsSize) XmlGetAttributes(enc, s, n, atts); } appAtts = (const XML_Char **)atts; for (i = 0; i < n; i++) { ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name, atts[i].name + XmlNameLength(enc, atts[i].name)); if (!attId) return XML_ERROR_NO_MEMORY; if ((attId->name)[-1]) { if (enc == encoding) eventPtr = atts[i].name; return XML_ERROR_DUPLICATE_ATTRIBUTE; } (attId->name)[-1] = 1; appAtts[attIndex++] = attId->name; if (!atts[i].normalized) { enum XML_Error result; int isCdata = 1; if (attId->maybeTokenized) { int j; for (j = 0; j < nDefaultAtts; j++) { if (attId == elementType->defaultAtts[j].id) { isCdata = elementType->defaultAtts[j].isCdata; break; } } } result = storeAttributeValue(parser, enc, isCdata, atts[i].valuePtr, atts[i].valueEnd, &tempPool); if (result) return result; if (tagNamePtr) { appAtts[attIndex] = poolStart(&tempPool); poolFinish(&tempPool); } else poolDiscard(&tempPool); } else if (tagNamePtr) { appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd); if (appAtts[attIndex] == 0) return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); } if (attId->prefix && tagNamePtr) { if (attId->xmlns) { if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr)) return XML_ERROR_NO_MEMORY; --attIndex; } else { attIndex++; nPrefixes++; (attId->name)[-1] = 2; } } else attIndex++; } nSpecifiedAtts = attIndex; if (tagNamePtr) { int j; for (j = 0; j < nDefaultAtts; j++) { const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j; if (!(da->id->name)[-1] && da->value) { if (da->id->prefix) { if (da->id->xmlns) { if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr)) return XML_ERROR_NO_MEMORY; } else { (da->id->name)[-1] = 2; nPrefixes++; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } } else { (da->id->name)[-1] = 1; appAtts[attIndex++] = da->id->name; appAtts[attIndex++] = da->value; } } } appAtts[attIndex] = 0; } i = 0; if (nPrefixes) { for (; i < attIndex; i += 2) { if (appAtts[i][-1] == 2) { ATTRIBUTE_ID *id; ((XML_Char *)(appAtts[i]))[-1] = 0; id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0); if (id->prefix->binding) { int j; const BINDING *b = id->prefix->binding; const XML_Char *ss = appAtts[i]; for (j = 0; j < b->uriLen; j++) { if (!poolAppendChar(&tempPool, b->uri[j])) return XML_ERROR_NO_MEMORY; } while (*ss++ != ':') ; do { if (!poolAppendChar(&tempPool, *ss)) return XML_ERROR_NO_MEMORY; } while (*ss++); appAtts[i] = poolStart(&tempPool); poolFinish(&tempPool); } if (!--nPrefixes) break; } else ((XML_Char *)(appAtts[i]))[-1] = 0; } } for (; i < attIndex; i += 2) ((XML_Char *)(appAtts[i]))[-1] = 0; if (!tagNamePtr) return XML_ERROR_NONE; for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding) binding->attId->name[-1] = 0; if (elementType->prefix) { binding = elementType->prefix->binding; if (!binding) return XML_ERROR_NONE; localPart = tagNamePtr->str; while (*localPart++ != XML_T(':')) ; } else if (dtd.defaultPrefix.binding) { binding = dtd.defaultPrefix.binding; localPart = tagNamePtr->str; } else return XML_ERROR_NONE; tagNamePtr->localPart = localPart; tagNamePtr->uriLen = binding->uriLen; i = binding->uriLen; do { if (i == binding->uriAlloc) { binding->uri = realloc(binding->uri, binding->uriAlloc *= 2); if (!binding->uri) return XML_ERROR_NO_MEMORY; } binding->uri[i++] = *localPart; } while (*localPart++); tagNamePtr->str = binding->uri; return XML_ERROR_NONE; } static int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr) { BINDING *b; int len; for (len = 0; uri[len]; len++) ; if (namespaceSeparator) len++; if (freeBindingList) { b = freeBindingList; if (len > b->uriAlloc) { b->uri = realloc(b->uri, len + EXPAND_SPARE); if (!b->uri) return 0; b->uriAlloc = len + EXPAND_SPARE; } freeBindingList = b->nextTagBinding; } else { b = malloc(sizeof(BINDING)); if (!b) return 0; b->uri = malloc(sizeof(XML_Char) * len + EXPAND_SPARE); if (!b->uri) { free(b); return 0; } b->uriAlloc = len; } b->uriLen = len; memcpy(b->uri, uri, len * sizeof(XML_Char)); if (namespaceSeparator) b->uri[len - 1] = namespaceSeparator; b->prefix = prefix; b->attId = attId; b->prevPrefixBinding = prefix->binding; if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix) prefix->binding = 0; else prefix->binding = b; b->nextTagBinding = *bindingsPtr; *bindingsPtr = b; if (startNamespaceDeclHandler) startNamespaceDeclHandler(handlerArg, prefix->name, prefix->binding ? uri : 0); return 1; } /* The idea here is to avoid using stack for each CDATA section when the whole file is parsed with one call. */ static enum XML_Error cdataSectionProcessor(XML_Parser parser, const char *start, const char *end, const char **endPtr) { enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr); if (start) { processor = contentProcessor; return contentProcessor(parser, start, end, endPtr); } return result; } /* startPtr gets set to non-null is the section is closed, and to null if the section is not yet closed. */ static enum XML_Error doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr, const char *end, const char **nextPtr) { const char *s = *startPtr; const char **eventPP; const char **eventEndPP; if (enc == encoding) { eventPP = &eventPtr; *eventPP = s; eventEndPP = &eventEndPtr; } else { eventPP = &(openInternalEntities->internalEventPtr); eventEndPP = &(openInternalEntities->internalEventEndPtr); } *eventPP = s; *startPtr = 0; for (;;) { const char *next; int tok = XmlCdataSectionTok(enc, s, end, &next); *eventEndPP = next; switch (tok) { case XML_TOK_CDATA_SECT_CLOSE: if (endCdataSectionHandler) endCdataSectionHandler(handlerArg); #if 0 /* see comment under XML_TOK_CDATA_SECT_OPEN */ else if (characterDataHandler) characterDataHandler(handlerArg, dataBuf, 0); #endif else if (defaultHandler) reportDefault(parser, enc, s, next); *startPtr = next; return XML_ERROR_NONE; case XML_TOK_DATA_NEWLINE: if (characterDataHandler) { XML_Char c = 0xA; characterDataHandler(handlerArg, &c, 1); } else if (defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_DATA_CHARS: if (characterDataHandler) { if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)dataBuf; XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); *eventEndPP = next; characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); if (s == next) break; *eventPP = s; } } else characterDataHandler(handlerArg, (XML_Char *)s, (XML_Char *)next - (XML_Char *)s); } else if (defaultHandler) reportDefault(parser, enc, s, next); break; case XML_TOK_INVALID: *eventPP = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL_CHAR: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; case XML_TOK_PARTIAL: case XML_TOK_NONE: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_CDATA_SECTION; default: abort(); } *eventPP = s = next; } /* not reached */ } static enum XML_Error initializeEncoding(XML_Parser parser) { const char *s; #ifdef XML_UNICODE char encodingBuf[128]; if (!protocolEncodingName) s = 0; else { int i; for (i = 0; protocolEncodingName[i]; i++) { if (i == sizeof(encodingBuf) - 1 || protocolEncodingName[i] >= 0x80 || protocolEncodingName[i] < 0) { encodingBuf[0] = '\0'; break; } encodingBuf[i] = (char)protocolEncodingName[i]; } encodingBuf[i] = '\0'; s = encodingBuf; } #else s = protocolEncodingName; #endif if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s)) return XML_ERROR_NONE; return handleUnknownEncoding(parser, protocolEncodingName); } static enum XML_Error processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s, const char *next) { const char *encodingName = 0; const ENCODING *newEncoding = 0; const char *version; int standalone = -1; if (!(ns ? XmlParseXmlDeclNS : XmlParseXmlDecl)(isGeneralTextEntity, encoding, s, next, &eventPtr, &version, &encodingName, &newEncoding, &standalone)) return XML_ERROR_SYNTAX; if (!isGeneralTextEntity && standalone == 1) dtd.standalone = 1; if (defaultHandler) reportDefault(parser, encoding, s, next); if (!protocolEncodingName) { if (newEncoding) { if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) { eventPtr = encodingName; return XML_ERROR_INCORRECT_ENCODING; } encoding = newEncoding; } else if (encodingName) { enum XML_Error result; const XML_Char *ss = poolStoreString(&tempPool, encoding, encodingName, encodingName + XmlNameLength(encoding, encodingName)); if (!ss) return XML_ERROR_NO_MEMORY; result = handleUnknownEncoding(parser, ss); poolDiscard(&tempPool); if (result == XML_ERROR_UNKNOWN_ENCODING) eventPtr = encodingName; return result; } } return XML_ERROR_NONE; } static enum XML_Error handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName) { if (unknownEncodingHandler) { XML_Encoding info; int i; for (i = 0; i < 256; i++) info.map[i] = -1; info.convert = 0; info.data = 0; info.release = 0; if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) { ENCODING *enc; unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding()); if (!unknownEncodingMem) { if (info.release) info.release(info.data); return XML_ERROR_NO_MEMORY; } enc = (ns ? XmlInitUnknownEncodingNS : XmlInitUnknownEncoding)(unknownEncodingMem, info.map, info.convert, info.data); if (enc) { unknownEncodingData = info.data; unknownEncodingRelease = info.release; encoding = enc; return XML_ERROR_NONE; } } if (info.release) info.release(info.data); } return XML_ERROR_UNKNOWN_ENCODING; } static enum XML_Error prologInitProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { enum XML_Error result = initializeEncoding(parser); if (result != XML_ERROR_NONE) return result; processor = prologProcessor; return prologProcessor(parser, s, end, nextPtr); } static enum XML_Error prologProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { for (;;) { const char *next; int tok = XmlPrologTok(encoding, s, end, &next); if (tok <= 0) { if (nextPtr != 0 && tok != XML_TOK_INVALID) { *nextPtr = s; return XML_ERROR_NONE; } switch (tok) { case XML_TOK_INVALID: eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_NONE: return XML_ERROR_NO_ELEMENTS; case XML_TOK_PARTIAL: return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: return XML_ERROR_PARTIAL_CHAR; case XML_TOK_TRAILING_CR: eventPtr = s + encoding->minBytesPerChar; return XML_ERROR_NO_ELEMENTS; default: abort(); } } switch (XmlTokenRole(&prologState, tok, s, next, encoding)) { case XML_ROLE_XML_DECL: { enum XML_Error result = processXmlDecl(parser, 0, s, next); if (result != XML_ERROR_NONE) return result; } break; case XML_ROLE_DOCTYPE_SYSTEM_ID: if (!dtd.standalone && notStandaloneHandler && !notStandaloneHandler(handlerArg)) return XML_ERROR_NOT_STANDALONE; hadExternalDoctype = 1; break; case XML_ROLE_DOCTYPE_PUBLIC_ID: case XML_ROLE_ENTITY_PUBLIC_ID: if (!XmlIsPublicId(encoding, s, next, &eventPtr)) return XML_ERROR_SYNTAX; if (declEntity) { XML_Char *tem = poolStoreString(&dtd.pool, encoding, s + encoding->minBytesPerChar, next - encoding->minBytesPerChar); if (!tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); declEntity->publicId = tem; poolFinish(&dtd.pool); } break; case XML_ROLE_INSTANCE_START: processor = contentProcessor; if (hadExternalDoctype) dtd.complete = 0; return contentProcessor(parser, s, end, nextPtr); case XML_ROLE_ATTLIST_ELEMENT_NAME: { const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next); if (!name) return XML_ERROR_NO_MEMORY; declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE)); if (!declElementType) return XML_ERROR_NO_MEMORY; if (declElementType->name != name) poolDiscard(&dtd.pool); else { poolFinish(&dtd.pool); if (!setElementTypePrefix(parser, declElementType)) return XML_ERROR_NO_MEMORY; } break; } case XML_ROLE_ATTRIBUTE_NAME: declAttributeId = getAttributeId(parser, encoding, s, next); if (!declAttributeId) return XML_ERROR_NO_MEMORY; declAttributeIsCdata = 0; break; case XML_ROLE_ATTRIBUTE_TYPE_CDATA: declAttributeIsCdata = 1; break; case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE: case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE: if (dtd.complete && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0)) return XML_ERROR_NO_MEMORY; break; case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE: case XML_ROLE_FIXED_ATTRIBUTE_VALUE: { const XML_Char *attVal; enum XML_Error result = storeAttributeValue(parser, encoding, declAttributeIsCdata, s + encoding->minBytesPerChar, next - encoding->minBytesPerChar, &dtd.pool); if (result) return result; attVal = poolStart(&dtd.pool); poolFinish(&dtd.pool); if (dtd.complete && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal)) return XML_ERROR_NO_MEMORY; break; } case XML_ROLE_ENTITY_VALUE: { enum XML_Error result = storeEntityValue(parser, s, next); if (result != XML_ERROR_NONE) return result; } break; case XML_ROLE_ENTITY_SYSTEM_ID: if (declEntity) { declEntity->systemId = poolStoreString(&dtd.pool, encoding, s + encoding->minBytesPerChar, next - encoding->minBytesPerChar); if (!declEntity->systemId) return XML_ERROR_NO_MEMORY; declEntity->base = dtd.base; poolFinish(&dtd.pool); } break; case XML_ROLE_ENTITY_NOTATION_NAME: if (declEntity) { declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next); if (!declEntity->notation) return XML_ERROR_NO_MEMORY; poolFinish(&dtd.pool); if (unparsedEntityDeclHandler) { eventPtr = eventEndPtr = s; unparsedEntityDeclHandler(handlerArg, declEntity->name, declEntity->base, declEntity->systemId, declEntity->publicId, declEntity->notation); } } break; case XML_ROLE_GENERAL_ENTITY_NAME: { const XML_Char *name; if (XmlPredefinedEntityName(encoding, s, next)) { declEntity = 0; break; } name = poolStoreString(&dtd.pool, encoding, s, next); if (!name) return XML_ERROR_NO_MEMORY; if (dtd.complete) { declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY)); if (!declEntity) return XML_ERROR_NO_MEMORY; if (declEntity->name != name) { poolDiscard(&dtd.pool); declEntity = 0; } else poolFinish(&dtd.pool); } else { poolDiscard(&dtd.pool); declEntity = 0; } } break; case XML_ROLE_PARAM_ENTITY_NAME: declEntity = 0; break; case XML_ROLE_NOTATION_NAME: declNotationPublicId = 0; declNotationName = 0; if (notationDeclHandler) { declNotationName = poolStoreString(&tempPool, encoding, s, next); if (!declNotationName) return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); } break; case XML_ROLE_NOTATION_PUBLIC_ID: if (!XmlIsPublicId(encoding, s, next, &eventPtr)) return XML_ERROR_SYNTAX; if (declNotationName) { XML_Char *tem = poolStoreString(&tempPool, encoding, s + encoding->minBytesPerChar, next - encoding->minBytesPerChar); if (!tem) return XML_ERROR_NO_MEMORY; normalizePublicId(tem); declNotationPublicId = tem; poolFinish(&tempPool); } break; case XML_ROLE_NOTATION_SYSTEM_ID: if (declNotationName && notationDeclHandler) { const XML_Char *systemId = poolStoreString(&tempPool, encoding, s + encoding->minBytesPerChar, next - encoding->minBytesPerChar); if (!systemId) return XML_ERROR_NO_MEMORY; eventPtr = eventEndPtr = s; notationDeclHandler(handlerArg, declNotationName, dtd.base, systemId, declNotationPublicId); } poolClear(&tempPool); break; case XML_ROLE_NOTATION_NO_SYSTEM_ID: if (declNotationPublicId && notationDeclHandler) { eventPtr = eventEndPtr = s; notationDeclHandler(handlerArg, declNotationName, dtd.base, 0, declNotationPublicId); } poolClear(&tempPool); break; case XML_ROLE_ERROR: eventPtr = s; switch (tok) { case XML_TOK_PARAM_ENTITY_REF: return XML_ERROR_PARAM_ENTITY_REF; case XML_TOK_XML_DECL: return XML_ERROR_MISPLACED_XML_PI; default: return XML_ERROR_SYNTAX; } case XML_ROLE_GROUP_OPEN: if (prologState.level >= groupSize) { if (groupSize) groupConnector = realloc(groupConnector, groupSize *= 2); else groupConnector = malloc(groupSize = 32); if (!groupConnector) return XML_ERROR_NO_MEMORY; } groupConnector[prologState.level] = 0; break; case XML_ROLE_GROUP_SEQUENCE: if (groupConnector[prologState.level] == '|') { eventPtr = s; return XML_ERROR_SYNTAX; } groupConnector[prologState.level] = ','; break; case XML_ROLE_GROUP_CHOICE: if (groupConnector[prologState.level] == ',') { eventPtr = s; return XML_ERROR_SYNTAX; } groupConnector[prologState.level] = '|'; break; case XML_ROLE_PARAM_ENTITY_REF: if (!dtd.standalone && notStandaloneHandler && !notStandaloneHandler(handlerArg)) return XML_ERROR_NOT_STANDALONE; dtd.complete = 0; break; case XML_ROLE_NONE: switch (tok) { case XML_TOK_PI: eventPtr = s; eventEndPtr = next; if (!reportProcessingInstruction(parser, encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: eventPtr = s; eventEndPtr = next; if (!reportComment(parser, encoding, s, next)) return XML_ERROR_NO_MEMORY; break; } break; } if (defaultHandler) { switch (tok) { case XML_TOK_PI: case XML_TOK_COMMENT: case XML_TOK_BOM: case XML_TOK_XML_DECL: break; default: eventPtr = s; eventEndPtr = next; reportDefault(parser, encoding, s, next); } } s = next; } /* not reached */ } static enum XML_Error epilogProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { processor = epilogProcessor; eventPtr = s; for (;;) { const char *next; int tok = XmlPrologTok(encoding, s, end, &next); eventEndPtr = next; switch (tok) { case XML_TOK_TRAILING_CR: if (defaultHandler) { eventEndPtr = end; reportDefault(parser, encoding, s, end); } /* fall through */ case XML_TOK_NONE: if (nextPtr) *nextPtr = end; return XML_ERROR_NONE; case XML_TOK_PROLOG_S: if (defaultHandler) reportDefault(parser, encoding, s, next); break; case XML_TOK_PI: if (!reportProcessingInstruction(parser, encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_COMMENT: if (!reportComment(parser, encoding, s, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_INVALID: eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_UNCLOSED_TOKEN; case XML_TOK_PARTIAL_CHAR: if (nextPtr) { *nextPtr = s; return XML_ERROR_NONE; } return XML_ERROR_PARTIAL_CHAR; default: return XML_ERROR_JUNK_AFTER_DOC_ELEMENT; } eventPtr = s = next; } } #if 0 static enum XML_Error errorProcessor(XML_Parser parser, const char *s, const char *end, const char **nextPtr) { return errorCode; } #endif static enum XML_Error storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, const char *ptr, const char *end, STRING_POOL *pool) { enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool); if (result) return result; if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20) poolChop(pool); if (!poolAppendChar(pool, XML_T('\0'))) return XML_ERROR_NO_MEMORY; return XML_ERROR_NONE; } static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata, const char *ptr, const char *end, STRING_POOL *pool) { const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); for (;;) { const char *next; int tok = XmlAttributeValueTok(enc, ptr, end, &next); switch (tok) { case XML_TOK_NONE: return XML_ERROR_NONE; case XML_TOK_INVALID: if (enc == encoding) eventPtr = next; return XML_ERROR_INVALID_TOKEN; case XML_TOK_PARTIAL: if (enc == encoding) eventPtr = ptr; return XML_ERROR_INVALID_TOKEN; case XML_TOK_CHAR_REF: { XML_Char buf[XML_ENCODE_MAX]; int i; int n = XmlCharRefNumber(enc, ptr); if (n < 0) { if (enc == encoding) eventPtr = ptr; return XML_ERROR_BAD_CHAR_REF; } if (!isCdata && n == 0x20 /* space */ && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) break; n = XmlEncode(n, (ICHAR *)buf); if (!n) { if (enc == encoding) eventPtr = ptr; return XML_ERROR_BAD_CHAR_REF; } for (i = 0; i < n; i++) { if (!poolAppendChar(pool, buf[i])) return XML_ERROR_NO_MEMORY; } } break; case XML_TOK_DATA_CHARS: if (!poolAppend(pool, enc, ptr, next)) return XML_ERROR_NO_MEMORY; break; break; case XML_TOK_TRAILING_CR: next = ptr + enc->minBytesPerChar; /* fall through */ case XML_TOK_ATTRIBUTE_VALUE_S: case XML_TOK_DATA_NEWLINE: if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20)) break; if (!poolAppendChar(pool, 0x20)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_ENTITY_REF: { const XML_Char *name; ENTITY *entity; XML_Char ch = XmlPredefinedEntityName(enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (ch) { if (!poolAppendChar(pool, ch)) return XML_ERROR_NO_MEMORY; break; } name = poolStoreString(&temp2Pool, enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar); if (!name) return XML_ERROR_NO_MEMORY; entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0); poolDiscard(&temp2Pool); if (!entity) { if (dtd.complete) { if (enc == encoding) eventPtr = ptr; return XML_ERROR_UNDEFINED_ENTITY; } } else if (entity->open) { if (enc == encoding) eventPtr = ptr; return XML_ERROR_RECURSIVE_ENTITY_REF; } else if (entity->notation) { if (enc == encoding) eventPtr = ptr; return XML_ERROR_BINARY_ENTITY_REF; } else if (!entity->textPtr) { if (enc == encoding) eventPtr = ptr; return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; } else { enum XML_Error result; const XML_Char *textEnd = entity->textPtr + entity->textLen; entity->open = 1; result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); entity->open = 0; if (result) return result; } } break; default: abort(); } ptr = next; } /* not reached */ } static enum XML_Error storeEntityValue(XML_Parser parser, const char *entityTextPtr, const char *entityTextEnd) { #if 0 const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(); #endif STRING_POOL *pool = &(dtd.pool); entityTextPtr += encoding->minBytesPerChar; entityTextEnd -= encoding->minBytesPerChar; for (;;) { const char *next; int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next); switch (tok) { case XML_TOK_PARAM_ENTITY_REF: eventPtr = entityTextPtr; return XML_ERROR_SYNTAX; case XML_TOK_NONE: if (declEntity) { declEntity->textPtr = pool->start; declEntity->textLen = pool->ptr - pool->start; poolFinish(pool); } else poolDiscard(pool); return XML_ERROR_NONE; case XML_TOK_ENTITY_REF: case XML_TOK_DATA_CHARS: if (!poolAppend(pool, encoding, entityTextPtr, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_TRAILING_CR: next = entityTextPtr + encoding->minBytesPerChar; /* fall through */ case XML_TOK_DATA_NEWLINE: if (pool->end == pool->ptr && !poolGrow(pool)) return XML_ERROR_NO_MEMORY; *(pool->ptr)++ = 0xA; break; case XML_TOK_CHAR_REF: { XML_Char buf[XML_ENCODE_MAX]; int i; int n = XmlCharRefNumber(encoding, entityTextPtr); if (n < 0) { eventPtr = entityTextPtr; return XML_ERROR_BAD_CHAR_REF; } n = XmlEncode(n, (ICHAR *)buf); if (!n) { eventPtr = entityTextPtr; return XML_ERROR_BAD_CHAR_REF; } for (i = 0; i < n; i++) { if (pool->end == pool->ptr && !poolGrow(pool)) return XML_ERROR_NO_MEMORY; *(pool->ptr)++ = buf[i]; } } break; case XML_TOK_PARTIAL: eventPtr = entityTextPtr; return XML_ERROR_INVALID_TOKEN; case XML_TOK_INVALID: eventPtr = next; return XML_ERROR_INVALID_TOKEN; default: abort(); } entityTextPtr = next; } /* not reached */ } static void normalizeLines(XML_Char *s) { XML_Char *p; for (;; s++) { if (*s == XML_T('\0')) return; if (*s == 0xD) break; } p = s; do { if (*s == 0xD) { *p++ = 0xA; if (*++s == 0xA) s++; } else *p++ = *s++; } while (*s); *p = XML_T('\0'); } static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { const XML_Char *target; XML_Char *data; const char *tem; if (!processingInstructionHandler) { if (defaultHandler) reportDefault(parser, enc, start, end); return 1; } start += enc->minBytesPerChar * 2; tem = start + XmlNameLength(enc, start); target = poolStoreString(&tempPool, enc, start, tem); if (!target) return 0; poolFinish(&tempPool); data = poolStoreString(&tempPool, enc, XmlSkipS(enc, tem), end - enc->minBytesPerChar*2); if (!data) return 0; normalizeLines(data); processingInstructionHandler(handlerArg, target, data); poolClear(&tempPool); return 1; } static int reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { XML_Char *data; if (!commentHandler) { if (defaultHandler) reportDefault(parser, enc, start, end); return 1; } data = poolStoreString(&tempPool, enc, start + enc->minBytesPerChar * 4, end - enc->minBytesPerChar * 3); if (!data) return 0; normalizeLines(data); commentHandler(handlerArg, data); poolClear(&tempPool); return 1; } static void reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end) { if (MUST_CONVERT(enc, s)) { const char **eventPP; const char **eventEndPP; if (enc == encoding) { eventPP = &eventPtr; eventEndPP = &eventEndPtr; } else { eventPP = &(openInternalEntities->internalEventPtr); eventEndPP = &(openInternalEntities->internalEventEndPtr); } do { ICHAR *dataPtr = (ICHAR *)dataBuf; XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); *eventEndPP = s; defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); *eventPP = s; } while (s != end); } else defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s); } static int defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value) { DEFAULT_ATTRIBUTE *att; if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { type->allocDefaultAtts = 8; type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); } else { type->allocDefaultAtts *= 2; type->defaultAtts = realloc(type->defaultAtts, type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); } if (!type->defaultAtts) return 0; } att = type->defaultAtts + type->nDefaultAtts; att->id = attId; att->value = value; att->isCdata = isCdata; if (!isCdata) attId->maybeTokenized = 1; type->nDefaultAtts += 1; return 1; } static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType) { const XML_Char *name; for (name = elementType->name; *name; name++) { if (*name == XML_T(':')) { PREFIX *prefix; const XML_Char *s; for (s = elementType->name; s != name; s++) { if (!poolAppendChar(&dtd.pool, *s)) return 0; } if (!poolAppendChar(&dtd.pool, XML_T('\0'))) return 0; prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX)); if (!prefix) return 0; if (prefix->name == poolStart(&dtd.pool)) poolFinish(&dtd.pool); else poolDiscard(&dtd.pool); elementType->prefix = prefix; } } return 1; } static ATTRIBUTE_ID * getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end) { ATTRIBUTE_ID *id; const XML_Char *name; if (!poolAppendChar(&dtd.pool, XML_T('\0'))) return 0; name = poolStoreString(&dtd.pool, enc, start, end); if (!name) return 0; ++name; id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID)); if (!id) return 0; if (id->name != name) poolDiscard(&dtd.pool); else { poolFinish(&dtd.pool); if (!ns) ; else if (name[0] == 'x' && name[1] == 'm' && name[2] == 'l' && name[3] == 'n' && name[4] == 's' && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) { if (name[5] == '\0') id->prefix = &dtd.defaultPrefix; else id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX)); id->xmlns = 1; } else { int i; for (i = 0; name[i]; i++) { if (name[i] == XML_T(':')) { int j; for (j = 0; j < i; j++) { if (!poolAppendChar(&dtd.pool, name[j])) return 0; } if (!poolAppendChar(&dtd.pool, XML_T('\0'))) return 0; id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX)); if (id->prefix->name == poolStart(&dtd.pool)) poolFinish(&dtd.pool); else poolDiscard(&dtd.pool); break; } } } } return id; } #define CONTEXT_SEP XML_T('\f') static const XML_Char *getContext(XML_Parser parser) { HASH_TABLE_ITER iter; int needSep = 0; if (dtd.defaultPrefix.binding) { int i; int len; if (!poolAppendChar(&tempPool, XML_T('='))) return 0; len = dtd.defaultPrefix.binding->uriLen; if (namespaceSeparator != XML_T('\0')) len--; for (i = 0; i < len; i++) if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i])) return 0; needSep = 1; } hashTableIterInit(&iter, &(dtd.prefixes)); for (;;) { int i; int len; const XML_Char *s; PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter); if (!prefix) break; if (!prefix->binding) continue; if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) return 0; for (s = prefix->name; *s; s++) if (!poolAppendChar(&tempPool, *s)) return 0; if (!poolAppendChar(&tempPool, XML_T('='))) return 0; len = prefix->binding->uriLen; if (namespaceSeparator != XML_T('\0')) len--; for (i = 0; i < len; i++) if (!poolAppendChar(&tempPool, prefix->binding->uri[i])) return 0; needSep = 1; } hashTableIterInit(&iter, &(dtd.generalEntities)); for (;;) { const XML_Char *s; ENTITY *e = (ENTITY *)hashTableIterNext(&iter); if (!e) break; if (!e->open) continue; if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP)) return 0; for (s = e->name; *s; s++) if (!poolAppendChar(&tempPool, *s)) return 0; needSep = 1; } if (!poolAppendChar(&tempPool, XML_T('\0'))) return 0; return tempPool.start; } static int setContext(XML_Parser parser, const XML_Char *context) { const XML_Char *s = context; while (*context != XML_T('\0')) { if (*s == CONTEXT_SEP || *s == XML_T('\0')) { ENTITY *e; if (!poolAppendChar(&tempPool, XML_T('\0'))) return 0; e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0); if (e) e->open = 1; if (*s != XML_T('\0')) s++; context = s; poolDiscard(&tempPool); } else if (*s == '=') { PREFIX *prefix; if (poolLength(&tempPool) == 0) prefix = &dtd.defaultPrefix; else { if (!poolAppendChar(&tempPool, XML_T('\0'))) return 0; prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX)); if (!prefix) return 0; if (prefix->name == poolStart(&tempPool)) poolFinish(&tempPool); else poolDiscard(&tempPool); } for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++) if (!poolAppendChar(&tempPool, *context)) return 0; if (!poolAppendChar(&tempPool, XML_T('\0'))) return 0; if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings)) return 0; poolDiscard(&tempPool); if (*context != XML_T('\0')) ++context; s = context; } else { if (!poolAppendChar(&tempPool, *s)) return 0; s++; } } return 1; } static void normalizePublicId(XML_Char *publicId) { XML_Char *p = publicId; XML_Char *s; for (s = publicId; *s; s++) { switch (*s) { case 0x20: case 0xD: case 0xA: if (p != publicId && p[-1] != 0x20) *p++ = 0x20; break; default: *p++ = *s; } } if (p != publicId && p[-1] == 0x20) --p; *p = XML_T('\0'); } static int dtdInit(DTD *p) { poolInit(&(p->pool)); hashTableInit(&(p->generalEntities)); hashTableInit(&(p->elementTypes)); hashTableInit(&(p->attributeIds)); hashTableInit(&(p->prefixes)); p->complete = 1; p->standalone = 0; p->base = 0; p->defaultPrefix.name = 0; p->defaultPrefix.binding = 0; return 1; } static void dtdDestroy(DTD *p) { HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(p->elementTypes)); for (;;) { ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (!e) break; if (e->allocDefaultAtts != 0) free(e->defaultAtts); } hashTableDestroy(&(p->generalEntities)); hashTableDestroy(&(p->elementTypes)); hashTableDestroy(&(p->attributeIds)); hashTableDestroy(&(p->prefixes)); poolDestroy(&(p->pool)); } /* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise. The new DTD has already been initialized. */ static int dtdCopy(DTD *newDtd, const DTD *oldDtd) { HASH_TABLE_ITER iter; if (oldDtd->base) { const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base); if (!tem) return 0; newDtd->base = tem; } /* Copy the prefix table. */ hashTableIterInit(&iter, &(oldDtd->prefixes)); for (;;) { const XML_Char *name; const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter); if (!oldP) break; name = poolCopyString(&(newDtd->pool), oldP->name); if (!name) return 0; if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX))) return 0; } hashTableIterInit(&iter, &(oldDtd->attributeIds)); /* Copy the attribute id table. */ for (;;) { ATTRIBUTE_ID *newA; const XML_Char *name; const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); if (!oldA) break; /* Remember to allocate the scratch byte before the name. */ if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) return 0; name = poolCopyString(&(newDtd->pool), oldA->name); if (!name) return 0; ++name; newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); if (!newA) return 0; newA->maybeTokenized = oldA->maybeTokenized; if (oldA->prefix) { newA->xmlns = oldA->xmlns; if (oldA->prefix == &oldDtd->defaultPrefix) newA->prefix = &newDtd->defaultPrefix; else newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0); } } /* Copy the element type table. */ hashTableIterInit(&iter, &(oldDtd->elementTypes)); for (;;) { int i; ELEMENT_TYPE *newE; const XML_Char *name; const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (!oldE) break; name = poolCopyString(&(newDtd->pool), oldE->name); if (!name) return 0; newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); if (!newE) return 0; if (oldE->nDefaultAtts) { newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (!newE->defaultAtts) return 0; } newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; if (oldE->prefix) newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0); for (i = 0; i < newE->nDefaultAtts; i++) { newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; if (oldE->defaultAtts[i].value) { newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); if (!newE->defaultAtts[i].value) return 0; } else newE->defaultAtts[i].value = 0; } } /* Copy the entity table. */ hashTableIterInit(&iter, &(oldDtd->generalEntities)); for (;;) { ENTITY *newE; const XML_Char *name; const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); if (!oldE) break; name = poolCopyString(&(newDtd->pool), oldE->name); if (!name) return 0; newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY)); if (!newE) return 0; if (oldE->systemId) { const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId); if (!tem) return 0; newE->systemId = tem; if (oldE->base) { if (oldE->base == oldDtd->base) newE->base = newDtd->base; tem = poolCopyString(&(newDtd->pool), oldE->base); if (!tem) return 0; newE->base = tem; } } else { const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen); if (!tem) return 0; newE->textPtr = tem; newE->textLen = oldE->textLen; } if (oldE->notation) { const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation); if (!tem) return 0; newE->notation = tem; } } newDtd->complete = oldDtd->complete; newDtd->standalone = oldDtd->standalone; return 1; } static void poolInit(STRING_POOL *pool) { pool->blocks = 0; pool->freeBlocks = 0; pool->start = 0; pool->ptr = 0; pool->end = 0; } static void poolClear(STRING_POOL *pool) { if (!pool->freeBlocks) pool->freeBlocks = pool->blocks; else { BLOCK *p = pool->blocks; while (p) { BLOCK *tem = p->next; p->next = pool->freeBlocks; pool->freeBlocks = p; p = tem; } } pool->blocks = 0; pool->start = 0; pool->ptr = 0; pool->end = 0; } static void poolDestroy(STRING_POOL *pool) { BLOCK *p = pool->blocks; while (p) { BLOCK *tem = p->next; free(p); p = tem; } pool->blocks = 0; p = pool->freeBlocks; while (p) { BLOCK *tem = p->next; free(p); p = tem; } pool->freeBlocks = 0; pool->ptr = 0; pool->start = 0; pool->end = 0; } static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end) { if (!pool->ptr && !poolGrow(pool)) return 0; for (;;) { XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); if (ptr == end) break; if (!poolGrow(pool)) return 0; } return pool->start; } static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s) { do { if (!poolAppendChar(pool, *s)) return 0; } while (*s++); s = pool->start; poolFinish(pool); return s; } static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n) { if (!pool->ptr && !poolGrow(pool)) return 0; for (; n > 0; --n, s++) { if (!poolAppendChar(pool, *s)) return 0; } s = pool->start; poolFinish(pool); return s; } static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc, const char *ptr, const char *end) { if (!poolAppend(pool, enc, ptr, end)) return 0; if (pool->ptr == pool->end && !poolGrow(pool)) return 0; *(pool->ptr)++ = 0; return pool->start; } static int poolGrow(STRING_POOL *pool) { if (pool->freeBlocks) { if (pool->start == 0) { pool->blocks = pool->freeBlocks; pool->freeBlocks = pool->freeBlocks->next; pool->blocks->next = 0; pool->start = pool->blocks->s; pool->end = pool->start + pool->blocks->size; pool->ptr = pool->start; return 1; } if (pool->end - pool->start < pool->freeBlocks->size) { BLOCK *tem = pool->freeBlocks->next; pool->freeBlocks->next = pool->blocks; pool->blocks = pool->freeBlocks; pool->freeBlocks = tem; memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char)); pool->ptr = pool->blocks->s + (pool->ptr - pool->start); pool->start = pool->blocks->s; pool->end = pool->start + pool->blocks->size; return 1; } } if (pool->blocks && pool->start == pool->blocks->s) { int blockSize = (pool->end - pool->start)*2; pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char)); if (!pool->blocks) return 0; pool->blocks->size = blockSize; pool->ptr = pool->blocks->s + (pool->ptr - pool->start); pool->start = pool->blocks->s; pool->end = pool->start + blockSize; } else { BLOCK *tem; int blockSize = pool->end - pool->start; if (blockSize < INIT_BLOCK_SIZE) blockSize = INIT_BLOCK_SIZE; else blockSize *= 2; tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char)); if (!tem) return 0; tem->size = blockSize; tem->next = pool->blocks; pool->blocks = tem; memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char)); pool->ptr = tem->s + (pool->ptr - pool->start); pool->start = tem->s; pool->end = tem->s + blockSize; } return 1; } 1.1 apache-apr/pthreads/src/lib/expat-lite/xmlparse.h Index: xmlparse.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #ifndef XmlParse_INCLUDED #define XmlParse_INCLUDED 1 #ifdef __cplusplus extern "C" { #endif #ifndef XMLPARSEAPI #define XMLPARSEAPI /* as nothing */ #endif typedef void *XML_Parser; #ifdef XML_UNICODE_WCHAR_T /* XML_UNICODE_WCHAR_T will work only if sizeof(wchar_t) == 2 and wchar_t uses Unicode. */ /* Information is UTF-16 encoded as wchar_ts */ #ifndef XML_UNICODE #define XML_UNICODE #endif #include <stddef.h> typedef wchar_t XML_Char; typedef wchar_t XML_LChar; #else /* not XML_UNICODE_WCHAR_T */ #ifdef XML_UNICODE /* Information is UTF-16 encoded as unsigned shorts */ typedef unsigned short XML_Char; typedef char XML_LChar; #else /* not XML_UNICODE */ /* Information is UTF-8 encoded. */ typedef char XML_Char; typedef char XML_LChar; #endif /* not XML_UNICODE */ #endif /* not XML_UNICODE_WCHAR_T */ /* Constructs a new parser; encoding is the encoding specified by the external protocol or null if there is none specified. */ XML_Parser XMLPARSEAPI XML_ParserCreate(const XML_Char *encoding); /* Constructs a new parser and namespace processor. Element type names and attribute names that belong to a namespace will be expanded; unprefixed attribute names are never expanded; unprefixed element type names are expanded only if there is a default namespace. The expanded name is the concatenation of the namespace URI, the namespace separator character, and the local part of the name. If the namespace separator is '\0' then the namespace URI and the local part will be concatenated without any separator. When a namespace is not declared, the name and prefix will be passed through without expansion. */ XML_Parser XMLPARSEAPI XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); /* atts is array of name/value pairs, terminated by 0; names and values are 0 terminated. */ typedef void (*XML_StartElementHandler)(void *userData, const XML_Char *name, const XML_Char **atts); typedef void (*XML_EndElementHandler)(void *userData, const XML_Char *name); /* s is not 0 terminated. */ typedef void (*XML_CharacterDataHandler)(void *userData, const XML_Char *s, int len); /* target and data are 0 terminated */ typedef void (*XML_ProcessingInstructionHandler)(void *userData, const XML_Char *target, const XML_Char *data); /* data is 0 terminated */ typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data); typedef void (*XML_StartCdataSectionHandler)(void *userData); typedef void (*XML_EndCdataSectionHandler)(void *userData); /* This is called for any characters in the XML document for which there is no applicable handler. This includes both characters that are part of markup which is of a kind that is not reported (comments, markup declarations), or characters that are part of a construct which could be reported but for which no handler has been supplied. The characters are passed exactly as they were in the XML document except that they will be encoded in UTF-8. Line boundaries are not normalized. Note that a byte order mark character is not passed to the default handler. There are no guarantees about how characters are divided between calls to the default handler: for example, a comment might be split between multiple calls. */ typedef void (*XML_DefaultHandler)(void *userData, const XML_Char *s, int len); /* This is called for a declaration of an unparsed (NDATA) entity. The base argument is whatever was set by XML_SetBase. The entityName, systemId and notationName arguments will never be null. The other arguments may be. */ typedef void (*XML_UnparsedEntityDeclHandler)(void *userData, const XML_Char *entityName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId, const XML_Char *notationName); /* This is called for a declaration of notation. The base argument is whatever was set by XML_SetBase. The notationName will never be null. The other arguments can be. */ typedef void (*XML_NotationDeclHandler)(void *userData, const XML_Char *notationName, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); /* When namespace processing is enabled, these are called once for each namespace declaration. The call to the start and end element handlers occur between the calls to the start and end namespace declaration handlers. For an xmlns attribute, prefix will be null. For an xmlns="" attribute, uri will be null. */ typedef void (*XML_StartNamespaceDeclHandler)(void *userData, const XML_Char *prefix, const XML_Char *uri); typedef void (*XML_EndNamespaceDeclHandler)(void *userData, const XML_Char *prefix); /* This is called if the document is not standalone (it has an external subset or a reference to a parameter entity, but does not have standalone="yes"). If this handler returns 0, then processing will not continue, and the parser will return a XML_ERROR_NOT_STANDALONE error. */ typedef int (*XML_NotStandaloneHandler)(void *userData); /* This is called for a reference to an external parsed general entity. The referenced entity is not automatically parsed. The application can parse it immediately or later using XML_ExternalEntityParserCreate. The parser argument is the parser parsing the entity containing the reference; it can be passed as the parser argument to XML_ExternalEntityParserCreate. The systemId argument is the system identifier as specified in the entity declaration; it will not be null. The base argument is the system identifier that should be used as the base for resolving systemId if systemId was relative; this is set by XML_SetBase; it may be null. The publicId argument is the public identifier as specified in the entity declaration, or null if none was specified; the whitespace in the public identifier will have been normalized as required by the XML spec. The context argument specifies the parsing context in the format expected by the context argument to XML_ExternalEntityParserCreate; context is valid only until the handler returns, so if the referenced entity is to be parsed later, it must be copied. The handler should return 0 if processing should not continue because of a fatal error in the handling of the external entity. In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING error. Note that unlike other handlers the first argument is the parser, not userData. */ typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId); /* This structure is filled in by the XML_UnknownEncodingHandler to provide information to the parser about encodings that are unknown to the parser. The map[b] member gives information about byte sequences whose first byte is b. If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c. If map[b] is -1, then the byte sequence is malformed. If map[b] is -n, where n >= 2, then b is the first byte of an n-byte sequence that encodes a single Unicode scalar value. The data member will be passed as the first argument to the convert function. The convert function is used to convert multibyte sequences; s will point to a n-byte sequence where map[(unsigned char)*s] == -n. The convert function must return the Unicode scalar value represented by this byte sequence or -1 if the byte sequence is malformed. The convert function may be null if the encoding is a single-byte encoding, that is if map[b] >= -1 for all bytes b. When the parser is finished with the encoding, then if release is not null, it will call release passing it the data member; once release has been called, the convert function will not be called again. Expat places certain restrictions on the encodings that are supported using this mechanism. 1. Every ASCII character that can appear in a well-formed XML document, other than the characters [EMAIL PROTECTED] must be represented by a single byte, and that byte must be the same byte that represents that character in ASCII. 2. No character may require more than 4 bytes to encode. 3. All characters encoded must have Unicode scalar values <= 0xFFFF, (ie characters that would be encoded by surrogates in UTF-16 are not allowed). Note that this restriction doesn't apply to the built-in support for UTF-8 and UTF-16. 4. No Unicode character may be encoded by more than one distinct sequence of bytes. */ typedef struct { int map[256]; void *data; int (*convert)(void *data, const char *s); void (*release)(void *data); } XML_Encoding; /* This is called for an encoding that is unknown to the parser. The encodingHandlerData argument is that which was passed as the second argument to XML_SetUnknownEncodingHandler. The name argument gives the name of the encoding as specified in the encoding declaration. If the callback can provide information about the encoding, it must fill in the XML_Encoding structure, and return 1. Otherwise it must return 0. If info does not describe a suitable encoding, then the parser will return an XML_UNKNOWN_ENCODING error. */ typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info); void XMLPARSEAPI XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end); void XMLPARSEAPI XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler); void XMLPARSEAPI XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler); void XMLPARSEAPI XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler); void XMLPARSEAPI XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end); /* This sets the default handler and also inhibits expansion of internal entities. The entity reference will be passed to the default handler. */ void XMLPARSEAPI XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler); /* This sets the default handler but does not inhibit expansion of internal entities. The entity reference will not be passed to the default handler. */ void XMLPARSEAPI XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler); void XMLPARSEAPI XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler); void XMLPARSEAPI XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler); void XMLPARSEAPI XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end); void XMLPARSEAPI XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler); void XMLPARSEAPI XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler); /* If a non-null value for arg is specified here, then it will be passed as the first argument to the external entity ref handler instead of the parser object. */ void XMLPARSEAPI XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg); void XMLPARSEAPI XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *encodingHandlerData); /* This can be called within a handler for a start element, end element, processing instruction or character data. It causes the corresponding markup to be passed to the default handler. */ void XMLPARSEAPI XML_DefaultCurrent(XML_Parser parser); /* This value is passed as the userData argument to callbacks. */ void XMLPARSEAPI XML_SetUserData(XML_Parser parser, void *userData); /* Returns the last value set by XML_SetUserData or null. */ #define XML_GetUserData(parser) (*(void **)(parser)) /* This is equivalent to supplying an encoding argument to XML_CreateParser. It must not be called after XML_Parse or XML_ParseBuffer. */ int XMLPARSEAPI XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); /* If this function is called, then the parser will be passed as the first argument to callbacks instead of userData. The userData will still be accessible using XML_GetUserData. */ void XMLPARSEAPI XML_UseParserAsHandlerArg(XML_Parser parser); /* Sets the base to be used for resolving relative URIs in system identifiers in declarations. Resolving relative identifiers is left to the application: this value will be passed through as the base argument to the XML_ExternalEntityRefHandler, XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base argument will be copied. Returns zero if out of memory, non-zero otherwise. */ int XMLPARSEAPI XML_SetBase(XML_Parser parser, const XML_Char *base); const XML_Char XMLPARSEAPI * XML_GetBase(XML_Parser parser); /* Returns the number of the attributes passed in last call to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. */ int XMLPARSEAPI XML_GetSpecifiedAttributeCount(XML_Parser parser); /* Parses some input. Returns 0 if a fatal error is detected. The last call to XML_Parse must have isFinal true; len may be zero for this call (or any other). */ int XMLPARSEAPI XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); void XMLPARSEAPI * XML_GetBuffer(XML_Parser parser, int len); int XMLPARSEAPI XML_ParseBuffer(XML_Parser parser, int len, int isFinal); /* Creates an XML_Parser object that can parse an external general entity; context is a '\0'-terminated string specifying the parse context; encoding is a '\0'-terminated string giving the name of the externally specified encoding, or null if there is no externally specified encoding. The context string consists of a sequence of tokens separated by formfeeds (\f); a token consisting of a name specifies that the general entity of the name is open; a token of the form prefix=uri specifies the namespace for a particular prefix; a token of the form =uri specifies the default namespace. This can be called at any point after the first call to an ExternalEntityRefHandler so longer as the parser has not yet been freed. The new parser is completely independent and may safely be used in a separate thread. The handlers and userData are initialized from the parser argument. Returns 0 if out of memory. Otherwise returns a new XML_Parser object. */ XML_Parser XMLPARSEAPI XML_ExternalEntityParserCreate(XML_Parser parser, const XML_Char *context, const XML_Char *encoding); enum XML_Error { XML_ERROR_NONE, XML_ERROR_NO_MEMORY, XML_ERROR_SYNTAX, XML_ERROR_NO_ELEMENTS, XML_ERROR_INVALID_TOKEN, XML_ERROR_UNCLOSED_TOKEN, XML_ERROR_PARTIAL_CHAR, XML_ERROR_TAG_MISMATCH, XML_ERROR_DUPLICATE_ATTRIBUTE, XML_ERROR_JUNK_AFTER_DOC_ELEMENT, XML_ERROR_PARAM_ENTITY_REF, XML_ERROR_UNDEFINED_ENTITY, XML_ERROR_RECURSIVE_ENTITY_REF, XML_ERROR_ASYNC_ENTITY, XML_ERROR_BAD_CHAR_REF, XML_ERROR_BINARY_ENTITY_REF, XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, XML_ERROR_MISPLACED_XML_PI, XML_ERROR_UNKNOWN_ENCODING, XML_ERROR_INCORRECT_ENCODING, XML_ERROR_UNCLOSED_CDATA_SECTION, XML_ERROR_EXTERNAL_ENTITY_HANDLING, XML_ERROR_NOT_STANDALONE }; /* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode returns information about the error. */ enum XML_Error XMLPARSEAPI XML_GetErrorCode(XML_Parser parser); /* These functions return information about the current parse location. They may be called when XML_Parse or XML_ParseBuffer return 0; in this case the location is the location of the character at which the error was detected. They may also be called from any other callback called to report some parse event; in this the location is the location of the first of the sequence of characters that generated the event. */ int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser); int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser); long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser); /* Return the number of bytes in the current event. Returns 0 if the event is in an internal entity. */ int XMLPARSEAPI XML_GetCurrentByteCount(XML_Parser parser); /* For backwards compatibility with previous versions. */ #define XML_GetErrorLineNumber XML_GetCurrentLineNumber #define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber #define XML_GetErrorByteIndex XML_GetCurrentByteIndex /* Frees memory used by the parser. */ void XMLPARSEAPI XML_ParserFree(XML_Parser parser); /* Returns a string describing the error. */ const XML_LChar XMLPARSEAPI *XML_ErrorString(int code); #ifdef __cplusplus } #endif #endif /* not XmlParse_INCLUDED */ 1.1 apache-apr/pthreads/src/lib/expat-lite/xmlrole.c Index: xmlrole.c =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #include "xmldef.h" #include "xmlrole.h" /* Doesn't check: that ,| are not mixed in a model group content of literals */ #ifndef MIN_BYTES_PER_CHAR #define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar) #endif typedef int PROLOG_HANDLER(struct prolog_state *state, int tok, const char *ptr, const char *end, const ENCODING *enc); static PROLOG_HANDLER prolog0, prolog1, prolog2, doctype0, doctype1, doctype2, doctype3, doctype4, doctype5, internalSubset, entity0, entity1, entity2, entity3, entity4, entity5, entity6, entity7, entity8, entity9, notation0, notation1, notation2, notation3, notation4, attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6, attlist7, attlist8, attlist9, element0, element1, element2, element3, element4, element5, element6, element7, declClose, error; static int syntaxError(PROLOG_STATE *); static int prolog0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: state->handler = prolog1; return XML_ROLE_NONE; case XML_TOK_XML_DECL: state->handler = prolog1; return XML_ROLE_XML_DECL; case XML_TOK_PI: state->handler = prolog1; return XML_ROLE_NONE; case XML_TOK_COMMENT: state->handler = prolog1; case XML_TOK_BOM: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: if (!XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), "DOCTYPE")) break; state->handler = doctype0; return XML_ROLE_NONE; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return syntaxError(state); } static int prolog1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_PI: case XML_TOK_COMMENT: case XML_TOK_BOM: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: if (!XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), "DOCTYPE")) break; state->handler = doctype0; return XML_ROLE_NONE; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return syntaxError(state); } static int prolog2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_PI: case XML_TOK_COMMENT: return XML_ROLE_NONE; case XML_TOK_INSTANCE_START: state->handler = error; return XML_ROLE_INSTANCE_START; } return syntaxError(state); } static int doctype0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = doctype1; return XML_ROLE_DOCTYPE_NAME; } return syntaxError(state); } static int doctype1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = internalSubset; return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { state->handler = doctype3; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { state->handler = doctype2; return XML_ROLE_NONE; } break; } return syntaxError(state); } static int doctype2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = doctype3; return XML_ROLE_DOCTYPE_PUBLIC_ID; } return syntaxError(state); } static int doctype3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = doctype4; return XML_ROLE_DOCTYPE_SYSTEM_ID; } return syntaxError(state); } static int doctype4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_OPEN_BRACKET: state->handler = internalSubset; return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } return syntaxError(state); } static int doctype5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: state->handler = prolog2; return XML_ROLE_DOCTYPE_CLOSE; } return syntaxError(state); } static int internalSubset(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_OPEN: if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), "ENTITY")) { state->handler = entity0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), "ATTLIST")) { state->handler = attlist0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), "ELEMENT")) { state->handler = element0; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr + 2 * MIN_BYTES_PER_CHAR(enc), "NOTATION")) { state->handler = notation0; return XML_ROLE_NONE; } break; case XML_TOK_PI: case XML_TOK_COMMENT: return XML_ROLE_NONE; case XML_TOK_PARAM_ENTITY_REF: return XML_ROLE_PARAM_ENTITY_REF; case XML_TOK_CLOSE_BRACKET: state->handler = doctype5; return XML_ROLE_NONE; } return syntaxError(state); } static int entity0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_PERCENT: state->handler = entity1; return XML_ROLE_NONE; case XML_TOK_NAME: state->handler = entity2; return XML_ROLE_GENERAL_ENTITY_NAME; } return syntaxError(state); } static int entity1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: state->handler = entity7; return XML_ROLE_PARAM_ENTITY_NAME; } return syntaxError(state); } static int entity2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { state->handler = entity4; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { state->handler = entity3; return XML_ROLE_NONE; } break; case XML_TOK_LITERAL: state->handler = declClose; return XML_ROLE_ENTITY_VALUE; } return syntaxError(state); } static int entity3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = entity4; return XML_ROLE_ENTITY_PUBLIC_ID; } return syntaxError(state); } static int entity4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = entity5; return XML_ROLE_ENTITY_SYSTEM_ID; } return syntaxError(state); } static int entity5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: state->handler = internalSubset; return XML_ROLE_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, "NDATA")) { state->handler = entity6; return XML_ROLE_NONE; } break; } return syntaxError(state); } static int entity6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: state->handler = declClose; return XML_ROLE_ENTITY_NOTATION_NAME; } return syntaxError(state); } static int entity7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { state->handler = entity9; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { state->handler = entity8; return XML_ROLE_NONE; } break; case XML_TOK_LITERAL: state->handler = declClose; return XML_ROLE_ENTITY_VALUE; } return syntaxError(state); } static int entity8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = entity9; return XML_ROLE_ENTITY_PUBLIC_ID; } return syntaxError(state); } static int entity9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = declClose; return XML_ROLE_ENTITY_SYSTEM_ID; } return syntaxError(state); } static int notation0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: state->handler = notation1; return XML_ROLE_NOTATION_NAME; } return syntaxError(state); } static int notation1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) { state->handler = notation3; return XML_ROLE_NONE; } if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) { state->handler = notation2; return XML_ROLE_NONE; } break; } return syntaxError(state); } static int notation2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = notation4; return XML_ROLE_NOTATION_PUBLIC_ID; } return syntaxError(state); } static int notation3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = declClose; return XML_ROLE_NOTATION_SYSTEM_ID; } return syntaxError(state); } static int notation4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = declClose; return XML_ROLE_NOTATION_SYSTEM_ID; case XML_TOK_DECL_CLOSE: state->handler = internalSubset; return XML_ROLE_NOTATION_NO_SYSTEM_ID; } return syntaxError(state); } static int attlist0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist1; return XML_ROLE_ATTLIST_ELEMENT_NAME; } return syntaxError(state); } static int attlist1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: state->handler = internalSubset; return XML_ROLE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist2; return XML_ROLE_ATTRIBUTE_NAME; } return syntaxError(state); } static int attlist2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: { static const char *types[] = { "CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS", }; int i; for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++) if (XmlNameMatchesAscii(enc, ptr, types[i])) { state->handler = attlist8; return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i; } } if (XmlNameMatchesAscii(enc, ptr, "NOTATION")) { state->handler = attlist5; return XML_ROLE_NONE; } break; case XML_TOK_OPEN_PAREN: state->handler = attlist3; return XML_ROLE_NONE; } return syntaxError(state); } static int attlist3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NMTOKEN: case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = attlist4; return XML_ROLE_ATTRIBUTE_ENUM_VALUE; } return syntaxError(state); } static int attlist4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_CLOSE_PAREN: state->handler = attlist8; return XML_ROLE_NONE; case XML_TOK_OR: state->handler = attlist3; return XML_ROLE_NONE; } return syntaxError(state); } static int attlist5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_OPEN_PAREN: state->handler = attlist6; return XML_ROLE_NONE; } return syntaxError(state); } static int attlist6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: state->handler = attlist7; return XML_ROLE_ATTRIBUTE_NOTATION_VALUE; } return syntaxError(state); } static int attlist7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_CLOSE_PAREN: state->handler = attlist8; return XML_ROLE_NONE; case XML_TOK_OR: state->handler = attlist6; return XML_ROLE_NONE; } return syntaxError(state); } /* default value */ static int attlist8(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), "IMPLIED")) { state->handler = attlist1; return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), "REQUIRED")) { state->handler = attlist1; return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE; } if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), "FIXED")) { state->handler = attlist9; return XML_ROLE_NONE; } break; case XML_TOK_LITERAL: state->handler = attlist1; return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE; } return syntaxError(state); } static int attlist9(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_LITERAL: state->handler = attlist1; return XML_ROLE_FIXED_ATTRIBUTE_VALUE; } return syntaxError(state); } static int element0(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element1; return XML_ROLE_ELEMENT_NAME; } return syntaxError(state); } static int element1(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: if (XmlNameMatchesAscii(enc, ptr, "EMPTY")) { state->handler = declClose; return XML_ROLE_CONTENT_EMPTY; } if (XmlNameMatchesAscii(enc, ptr, "ANY")) { state->handler = declClose; return XML_ROLE_CONTENT_ANY; } break; case XML_TOK_OPEN_PAREN: state->handler = element2; state->level = 1; return XML_ROLE_GROUP_OPEN; } return syntaxError(state); } static int element2(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_POUND_NAME: if (XmlNameMatchesAscii(enc, ptr + MIN_BYTES_PER_CHAR(enc), "PCDATA")) { state->handler = element3; return XML_ROLE_CONTENT_PCDATA; } break; case XML_TOK_OPEN_PAREN: state->level = 2; state->handler = element6; return XML_ROLE_GROUP_OPEN; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT; case XML_TOK_NAME_QUESTION: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_OPT; case XML_TOK_NAME_ASTERISK: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_REP; case XML_TOK_NAME_PLUS: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } return syntaxError(state); } static int element3(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_CLOSE_PAREN: case XML_TOK_CLOSE_PAREN_ASTERISK: state->handler = declClose; return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_OR: state->handler = element4; return XML_ROLE_NONE; } return syntaxError(state); } static int element4(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element5; return XML_ROLE_CONTENT_ELEMENT; } return syntaxError(state); } static int element5(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_CLOSE_PAREN_ASTERISK: state->handler = declClose; return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_OR: state->handler = element4; return XML_ROLE_NONE; } return syntaxError(state); } static int element6(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_OPEN_PAREN: state->level += 1; return XML_ROLE_GROUP_OPEN; case XML_TOK_NAME: case XML_TOK_PREFIXED_NAME: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT; case XML_TOK_NAME_QUESTION: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_OPT; case XML_TOK_NAME_ASTERISK: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_REP; case XML_TOK_NAME_PLUS: state->handler = element7; return XML_ROLE_CONTENT_ELEMENT_PLUS; } return syntaxError(state); } static int element7(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_CLOSE_PAREN: state->level -= 1; if (state->level == 0) state->handler = declClose; return XML_ROLE_GROUP_CLOSE; case XML_TOK_CLOSE_PAREN_ASTERISK: state->level -= 1; if (state->level == 0) state->handler = declClose; return XML_ROLE_GROUP_CLOSE_REP; case XML_TOK_CLOSE_PAREN_QUESTION: state->level -= 1; if (state->level == 0) state->handler = declClose; return XML_ROLE_GROUP_CLOSE_OPT; case XML_TOK_CLOSE_PAREN_PLUS: state->level -= 1; if (state->level == 0) state->handler = declClose; return XML_ROLE_GROUP_CLOSE_PLUS; case XML_TOK_COMMA: state->handler = element6; return XML_ROLE_GROUP_SEQUENCE; case XML_TOK_OR: state->handler = element6; return XML_ROLE_GROUP_CHOICE; } return syntaxError(state); } static int declClose(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_PROLOG_S: return XML_ROLE_NONE; case XML_TOK_DECL_CLOSE: state->handler = internalSubset; return XML_ROLE_NONE; } return syntaxError(state); } #if 0 static int ignore(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { switch (tok) { case XML_TOK_DECL_CLOSE: state->handler = internalSubset; return 0; default: return XML_ROLE_NONE; } return syntaxError(state); } #endif static int error(PROLOG_STATE *state, int tok, const char *ptr, const char *end, const ENCODING *enc) { return XML_ROLE_NONE; } static int syntaxError(PROLOG_STATE *state) { state->handler = error; return XML_ROLE_ERROR; } void XmlPrologStateInit(PROLOG_STATE *state) { state->handler = prolog0; } 1.1 apache-apr/pthreads/src/lib/expat-lite/xmlrole.h Index: xmlrole.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #ifndef XmlRole_INCLUDED #define XmlRole_INCLUDED 1 #include "xmltok.h" #ifdef __cplusplus extern "C" { #endif enum { XML_ROLE_ERROR = -1, XML_ROLE_NONE = 0, XML_ROLE_XML_DECL, XML_ROLE_INSTANCE_START, XML_ROLE_DOCTYPE_NAME, XML_ROLE_DOCTYPE_SYSTEM_ID, XML_ROLE_DOCTYPE_PUBLIC_ID, XML_ROLE_DOCTYPE_CLOSE, XML_ROLE_GENERAL_ENTITY_NAME, XML_ROLE_PARAM_ENTITY_NAME, XML_ROLE_ENTITY_VALUE, XML_ROLE_ENTITY_SYSTEM_ID, XML_ROLE_ENTITY_PUBLIC_ID, XML_ROLE_ENTITY_NOTATION_NAME, XML_ROLE_NOTATION_NAME, XML_ROLE_NOTATION_SYSTEM_ID, XML_ROLE_NOTATION_NO_SYSTEM_ID, XML_ROLE_NOTATION_PUBLIC_ID, XML_ROLE_ATTRIBUTE_NAME, XML_ROLE_ATTRIBUTE_TYPE_CDATA, XML_ROLE_ATTRIBUTE_TYPE_ID, XML_ROLE_ATTRIBUTE_TYPE_IDREF, XML_ROLE_ATTRIBUTE_TYPE_IDREFS, XML_ROLE_ATTRIBUTE_TYPE_ENTITY, XML_ROLE_ATTRIBUTE_TYPE_ENTITIES, XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN, XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS, XML_ROLE_ATTRIBUTE_ENUM_VALUE, XML_ROLE_ATTRIBUTE_NOTATION_VALUE, XML_ROLE_ATTLIST_ELEMENT_NAME, XML_ROLE_IMPLIED_ATTRIBUTE_VALUE, XML_ROLE_REQUIRED_ATTRIBUTE_VALUE, XML_ROLE_DEFAULT_ATTRIBUTE_VALUE, XML_ROLE_FIXED_ATTRIBUTE_VALUE, XML_ROLE_ELEMENT_NAME, XML_ROLE_CONTENT_ANY, XML_ROLE_CONTENT_EMPTY, XML_ROLE_CONTENT_PCDATA, XML_ROLE_GROUP_OPEN, XML_ROLE_GROUP_CLOSE, XML_ROLE_GROUP_CLOSE_REP, XML_ROLE_GROUP_CLOSE_OPT, XML_ROLE_GROUP_CLOSE_PLUS, XML_ROLE_GROUP_CHOICE, XML_ROLE_GROUP_SEQUENCE, XML_ROLE_CONTENT_ELEMENT, XML_ROLE_CONTENT_ELEMENT_REP, XML_ROLE_CONTENT_ELEMENT_OPT, XML_ROLE_CONTENT_ELEMENT_PLUS, XML_ROLE_PARAM_ENTITY_REF }; typedef struct prolog_state { int (*handler)(struct prolog_state *state, int tok, const char *ptr, const char *end, const ENCODING *enc); unsigned level; } PROLOG_STATE; void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *); #define XmlTokenRole(state, tok, ptr, end, enc) \ (((state)->handler)(state, tok, ptr, end, enc)) #ifdef __cplusplus } #endif #endif /* not XmlRole_INCLUDED */ 1.1 apache-apr/pthreads/src/lib/expat-lite/xmltok.c Index: xmltok.c =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #include "xmldef.h" #include "xmltok.h" #include "nametab.h" #define VTABLE1 \ { PREFIX(prologTok), PREFIX(contentTok), PREFIX(cdataSectionTok) }, \ { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \ PREFIX(sameName), \ PREFIX(nameMatchesAscii), \ PREFIX(nameLength), \ PREFIX(skipS), \ PREFIX(getAtts), \ PREFIX(charRefNumber), \ PREFIX(predefinedEntityName), \ PREFIX(updatePosition), \ PREFIX(isPublicId) #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) #define UCS2_GET_NAMING(pages, hi, lo) \ (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F))) /* A 2 byte UTF-8 representation splits the characters 11 bits between the bottom 5 and 6 bits of the bytes. We need 8 bits to index into pages, 3 bits to add to that index and 5 bits to generate the mask. */ #define UTF8_GET_NAMING2(pages, byte) \ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + ((((byte)[0]) & 3) << 1) \ + ((((byte)[1]) >> 5) & 1)] \ & (1 << (((byte)[1]) & 0x1F))) /* A 3 byte UTF-8 representation splits the characters 16 bits between the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index into pages, 3 bits to add to that index and 5 bits to generate the mask. */ #define UTF8_GET_NAMING3(pages, byte) \ (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \ + ((((byte)[1]) >> 2) & 0xF)] \ << 3) \ + ((((byte)[1]) & 3) << 1) \ + ((((byte)[2]) >> 5) & 1)] \ & (1 << (((byte)[2]) & 0x1F))) #define UTF8_GET_NAMING(pages, p, n) \ ((n) == 2 \ ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ : ((n) == 3 \ ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \ : 0)) #define UTF8_INVALID3(p) \ ((*p) == 0xED \ ? (((p)[1] & 0x20) != 0) \ : ((*p) == 0xEF \ ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \ : 0)) #define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0) static int isNever(const ENCODING *enc, const char *p) { return 0; } static int utf8_isName2(const ENCODING *enc, const char *p) { return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); } static int utf8_isName3(const ENCODING *enc, const char *p) { return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); } #define utf8_isName4 isNever static int utf8_isNmstrt2(const ENCODING *enc, const char *p) { return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); } static int utf8_isNmstrt3(const ENCODING *enc, const char *p) { return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); } #define utf8_isNmstrt4 isNever #define utf8_isInvalid2 isNever static int utf8_isInvalid3(const ENCODING *enc, const char *p) { return UTF8_INVALID3((const unsigned char *)p); } static int utf8_isInvalid4(const ENCODING *enc, const char *p) { return UTF8_INVALID4((const unsigned char *)p); } struct normal_encoding { ENCODING enc; unsigned char type[256]; #ifdef XML_MIN_SIZE int (*byteType)(const ENCODING *, const char *); int (*isNameMin)(const ENCODING *, const char *); int (*isNmstrtMin)(const ENCODING *, const char *); int (*byteToAscii)(const ENCODING *, const char *); int (*charMatches)(const ENCODING *, const char *, int); #endif /* XML_MIN_SIZE */ int (*isName2)(const ENCODING *, const char *); int (*isName3)(const ENCODING *, const char *); int (*isName4)(const ENCODING *, const char *); int (*isNmstrt2)(const ENCODING *, const char *); int (*isNmstrt3)(const ENCODING *, const char *); int (*isNmstrt4)(const ENCODING *, const char *); int (*isInvalid2)(const ENCODING *, const char *); int (*isInvalid3)(const ENCODING *, const char *); int (*isInvalid4)(const ENCODING *, const char *); }; #ifdef XML_MIN_SIZE #define STANDARD_VTABLE(E) \ E ## byteType, \ E ## isNameMin, \ E ## isNmstrtMin, \ E ## byteToAscii, \ E ## charMatches, #else #define STANDARD_VTABLE(E) /* as nothing */ #endif #define NORMAL_VTABLE(E) \ E ## isName2, \ E ## isName3, \ E ## isName4, \ E ## isNmstrt2, \ E ## isNmstrt3, \ E ## isNmstrt4, \ E ## isInvalid2, \ E ## isInvalid3, \ E ## isInvalid4 static int checkCharRefNumber(int); #include "xmltok_impl.h" #ifdef XML_MIN_SIZE #define sb_isNameMin isNever #define sb_isNmstrtMin isNever #endif #ifdef XML_MIN_SIZE #define MINBPC(enc) ((enc)->minBytesPerChar) #else /* minimum bytes per character */ #define MINBPC(enc) 1 #endif #define SB_BYTE_TYPE(enc, p) \ (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)]) #ifdef XML_MIN_SIZE static int sb_byteType(const ENCODING *enc, const char *p) { return SB_BYTE_TYPE(enc, p); } #define BYTE_TYPE(enc, p) \ (((const struct normal_encoding *)(enc))->byteType(enc, p)) #else #define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p) #endif #ifdef XML_MIN_SIZE #define BYTE_TO_ASCII(enc, p) \ (((const struct normal_encoding *)(enc))->byteToAscii(enc, p)) static int sb_byteToAscii(const ENCODING *enc, const char *p) { return *p; } #else #define BYTE_TO_ASCII(enc, p) (*p) #endif #define IS_NAME_CHAR(enc, p, n) \ (((const struct normal_encoding *)(enc))->isName ## n(enc, p)) #define IS_NMSTRT_CHAR(enc, p, n) \ (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p)) #define IS_INVALID_CHAR(enc, p, n) \ (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p)) #ifdef XML_MIN_SIZE #define IS_NAME_CHAR_MINBPC(enc, p) \ (((const struct normal_encoding *)(enc))->isNameMin(enc, p)) #define IS_NMSTRT_CHAR_MINBPC(enc, p) \ (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p)) #else #define IS_NAME_CHAR_MINBPC(enc, p) (0) #define IS_NMSTRT_CHAR_MINBPC(enc, p) (0) #endif #ifdef XML_MIN_SIZE #define CHAR_MATCHES(enc, p, c) \ (((const struct normal_encoding *)(enc))->charMatches(enc, p, c)) static int sb_charMatches(const ENCODING *enc, const char *p, int c) { return *p == c; } #else /* c is an ASCII character */ #define CHAR_MATCHES(enc, p, c) (*(p) == c) #endif #define PREFIX(ident) normal_ ## ident #include "xmltok_impl.c" #undef MINBPC #undef BYTE_TYPE #undef BYTE_TO_ASCII #undef CHAR_MATCHES #undef IS_NAME_CHAR #undef IS_NAME_CHAR_MINBPC #undef IS_NMSTRT_CHAR #undef IS_NMSTRT_CHAR_MINBPC #undef IS_INVALID_CHAR enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ UTF8_cval1 = 0x00, UTF8_cval2 = 0xc0, UTF8_cval3 = 0xe0, UTF8_cval4 = 0xf0 }; static void utf8_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { char *to; const char *from; if (fromLim - *fromP > toLim - *toP) { /* Avoid copying partial characters. */ for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) break; } for (to = *toP, from = *fromP; from != fromLim; from++, to++) *to = *from; *fromP = from; *toP = to; } static void utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { unsigned short *to = *toP; const char *from = *fromP; while (from != fromLim && to != toLim) { switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { case BT_LEAD2: *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f); from += 2; break; case BT_LEAD3: *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f); from += 3; break; case BT_LEAD4: { unsigned long n; if (to + 1 == toLim) break; n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); n -= 0x10000; to[0] = (unsigned short)((n >> 10) | 0xD800); to[1] = (unsigned short)((n & 0x3FF) | 0xDC00); to += 2; from += 4; } break; default: *to++ = *from++; break; } } *fromP = from; *toP = to; } #ifdef XML_NS static const struct normal_encoding utf8_encoding_ns = { { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, { #include "asciitab.h" #include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) }; #endif static const struct normal_encoding utf8_encoding = { { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) }; #ifdef XML_NS static const struct normal_encoding internal_utf8_encoding_ns = { { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, { #include "iasciitab.h" #include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) }; #endif static const struct normal_encoding internal_utf8_encoding = { { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 }, { #define BT_COLON BT_NMSTRT #include "iasciitab.h" #undef BT_COLON #include "utf8tab.h" }, STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) }; static void latin1_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { for (;;) { unsigned char c; if (*fromP == fromLim) break; c = (unsigned char)**fromP; if (c & 0x80) { if (toLim - *toP < 2) break; *(*toP)++ = ((c >> 6) | UTF8_cval2); *(*toP)++ = ((c & 0x3f) | 0x80); (*fromP)++; } else { if (*toP == toLim) break; *(*toP)++ = *(*fromP)++; } } } static void latin1_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { while (*fromP != fromLim && *toP != toLim) *(*toP)++ = (unsigned char)*(*fromP)++; } #ifdef XML_NS static const struct normal_encoding latin1_encoding_ns = { { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, { #include "asciitab.h" #include "latin1tab.h" }, STANDARD_VTABLE(sb_) }; #endif static const struct normal_encoding latin1_encoding = { { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(sb_) }; static void ascii_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { while (*fromP != fromLim && *toP != toLim) *(*toP)++ = *(*fromP)++; } #ifdef XML_NS static const struct normal_encoding ascii_encoding_ns = { { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, { #include "asciitab.h" /* BT_NONXML == 0 */ }, STANDARD_VTABLE(sb_) }; #endif static const struct normal_encoding ascii_encoding = { { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON /* BT_NONXML == 0 */ }, STANDARD_VTABLE(sb_) }; static int unicode_byte_type(char hi, char lo) { switch ((unsigned char)hi) { case 0xD8: case 0xD9: case 0xDA: case 0xDB: return BT_LEAD4; case 0xDC: case 0xDD: case 0xDE: case 0xDF: return BT_TRAIL; case 0xFF: switch ((unsigned char)lo) { case 0xFF: case 0xFE: return BT_NONXML; } break; } return BT_NONASCII; } #define DEFINE_UTF16_TO_UTF8(E) \ static \ void E ## toUtf8(const ENCODING *enc, \ const char **fromP, const char *fromLim, \ char **toP, const char *toLim) \ { \ const char *from; \ for (from = *fromP; from != fromLim; from += 2) { \ int plane; \ unsigned char lo2; \ unsigned char lo = GET_LO(from); \ unsigned char hi = GET_HI(from); \ switch (hi) { \ case 0: \ if (lo < 0x80) { \ if (*toP == toLim) { \ *fromP = from; \ return; \ } \ *(*toP)++ = lo; \ break; \ } \ /* fall through */ \ case 0x1: case 0x2: case 0x3: \ case 0x4: case 0x5: case 0x6: case 0x7: \ if (toLim - *toP < 2) { \ *fromP = from; \ return; \ } \ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ break; \ default: \ if (toLim - *toP < 3) { \ *fromP = from; \ return; \ } \ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ break; \ case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ if (toLim - *toP < 4) { \ *fromP = from; \ return; \ } \ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \ from += 2; \ lo2 = GET_LO(from); \ *(*toP)++ = (((lo & 0x3) << 4) \ | ((GET_HI(from) & 0x3) << 2) \ | (lo2 >> 6) \ | 0x80); \ *(*toP)++ = ((lo2 & 0x3f) | 0x80); \ break; \ } \ } \ *fromP = from; \ } #define DEFINE_UTF16_TO_UTF16(E) \ static \ void E ## toUtf16(const ENCODING *enc, \ const char **fromP, const char *fromLim, \ unsigned short **toP, const unsigned short *toLim) \ { \ /* Avoid copying first half only of surrogate */ \ if (fromLim - *fromP > ((toLim - *toP) << 1) \ && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ fromLim -= 2; \ for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ } #define SET2(ptr, ch) \ (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8))) #define GET_LO(ptr) ((unsigned char)(ptr)[0]) #define GET_HI(ptr) ((unsigned char)(ptr)[1]) DEFINE_UTF16_TO_UTF8(little2_) DEFINE_UTF16_TO_UTF16(little2_) #undef SET2 #undef GET_LO #undef GET_HI #define SET2(ptr, ch) \ (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF))) #define GET_LO(ptr) ((unsigned char)(ptr)[1]) #define GET_HI(ptr) ((unsigned char)(ptr)[0]) DEFINE_UTF16_TO_UTF8(big2_) DEFINE_UTF16_TO_UTF16(big2_) #undef SET2 #undef GET_LO #undef GET_HI #define LITTLE2_BYTE_TYPE(enc, p) \ ((p)[1] == 0 \ ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \ : unicode_byte_type((p)[1], (p)[0])) #define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1) #define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c) #define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0]) #define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0]) #ifdef XML_MIN_SIZE static int little2_byteType(const ENCODING *enc, const char *p) { return LITTLE2_BYTE_TYPE(enc, p); } static int little2_byteToAscii(const ENCODING *enc, const char *p) { return LITTLE2_BYTE_TO_ASCII(enc, p); } static int little2_charMatches(const ENCODING *enc, const char *p, int c) { return LITTLE2_CHAR_MATCHES(enc, p, c); } static int little2_isNameMin(const ENCODING *enc, const char *p) { return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p); } static int little2_isNmstrtMin(const ENCODING *enc, const char *p) { return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p); } #undef VTABLE #define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16 #else /* not XML_MIN_SIZE */ #undef PREFIX #define PREFIX(ident) little2_ ## ident #define MINBPC(enc) 2 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ #define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p) #define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) #define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c) #define IS_NAME_CHAR(enc, p, n) 0 #define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) #define IS_NMSTRT_CHAR(enc, p, n) (0) #define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) #include "xmltok_impl.c" #undef MINBPC #undef BYTE_TYPE #undef BYTE_TO_ASCII #undef CHAR_MATCHES #undef IS_NAME_CHAR #undef IS_NAME_CHAR_MINBPC #undef IS_NMSTRT_CHAR #undef IS_NMSTRT_CHAR_MINBPC #undef IS_INVALID_CHAR #endif /* not XML_MIN_SIZE */ #ifdef XML_NS static const struct normal_encoding little2_encoding_ns = { { VTABLE, 2, 0, #if XML_BYTE_ORDER == 12 1 #else 0 #endif }, { #include "asciitab.h" #include "latin1tab.h" }, STANDARD_VTABLE(little2_) }; #endif static const struct normal_encoding little2_encoding = { { VTABLE, 2, 0, #if XML_BYTE_ORDER == 12 1 #else 0 #endif }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(little2_) }; #if XML_BYTE_ORDER != 21 #ifdef XML_NS static const struct normal_encoding internal_little2_encoding_ns = { { VTABLE, 2, 0, 1 }, { #include "iasciitab.h" #include "latin1tab.h" }, STANDARD_VTABLE(little2_) }; #endif static const struct normal_encoding internal_little2_encoding = { { VTABLE, 2, 0, 1 }, { #define BT_COLON BT_NMSTRT #include "iasciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(little2_) }; #endif #define BIG2_BYTE_TYPE(enc, p) \ ((p)[0] == 0 \ ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \ : unicode_byte_type((p)[0], (p)[1])) #define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1) #define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c) #define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \ UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1]) #define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \ UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1]) #ifdef XML_MIN_SIZE static int big2_byteType(const ENCODING *enc, const char *p) { return BIG2_BYTE_TYPE(enc, p); } static int big2_byteToAscii(const ENCODING *enc, const char *p) { return BIG2_BYTE_TO_ASCII(enc, p); } static int big2_charMatches(const ENCODING *enc, const char *p, int c) { return BIG2_CHAR_MATCHES(enc, p, c); } static int big2_isNameMin(const ENCODING *enc, const char *p) { return BIG2_IS_NAME_CHAR_MINBPC(enc, p); } static int big2_isNmstrtMin(const ENCODING *enc, const char *p) { return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p); } #undef VTABLE #define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16 #else /* not XML_MIN_SIZE */ #undef PREFIX #define PREFIX(ident) big2_ ## ident #define MINBPC(enc) 2 /* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */ #define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p) #define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) #define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c) #define IS_NAME_CHAR(enc, p, n) 0 #define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p) #define IS_NMSTRT_CHAR(enc, p, n) (0) #define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) #include "xmltok_impl.c" #undef MINBPC #undef BYTE_TYPE #undef BYTE_TO_ASCII #undef CHAR_MATCHES #undef IS_NAME_CHAR #undef IS_NAME_CHAR_MINBPC #undef IS_NMSTRT_CHAR #undef IS_NMSTRT_CHAR_MINBPC #undef IS_INVALID_CHAR #endif /* not XML_MIN_SIZE */ #ifdef XML_NS static const struct normal_encoding big2_encoding_ns = { { VTABLE, 2, 0, #if XML_BYTE_ORDER == 21 1 #else 0 #endif }, { #include "asciitab.h" #include "latin1tab.h" }, STANDARD_VTABLE(big2_) }; #endif static const struct normal_encoding big2_encoding = { { VTABLE, 2, 0, #if XML_BYTE_ORDER == 21 1 #else 0 #endif }, { #define BT_COLON BT_NMSTRT #include "asciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(big2_) }; #if XML_BYTE_ORDER != 12 #ifdef XML_NS static const struct normal_encoding internal_big2_encoding_ns = { { VTABLE, 2, 0, 1 }, { #include "iasciitab.h" #include "latin1tab.h" }, STANDARD_VTABLE(big2_) }; #endif static const struct normal_encoding internal_big2_encoding = { { VTABLE, 2, 0, 1 }, { #define BT_COLON BT_NMSTRT #include "iasciitab.h" #undef BT_COLON #include "latin1tab.h" }, STANDARD_VTABLE(big2_) }; #endif #undef PREFIX static int streqci(const char *s1, const char *s2) { for (;;) { char c1 = *s1++; char c2 = *s2++; if ('a' <= c1 && c1 <= 'z') c1 += 'A' - 'a'; if ('a' <= c2 && c2 <= 'z') c2 += 'A' - 'a'; if (c1 != c2) return 0; if (!c1) break; } return 1; } static void initUpdatePosition(const ENCODING *enc, const char *ptr, const char *end, POSITION *pos) { normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); } static int toAscii(const ENCODING *enc, const char *ptr, const char *end) { char buf[1]; char *p = buf; XmlUtf8Convert(enc, &ptr, end, &p, p + 1); if (p == buf) return -1; else return buf[0]; } static int isSpace(int c) { switch (c) { case 0x20: case 0xD: case 0xA: case 0x9: return 1; } return 0; } /* Return 1 if there's just optional white space or there's an S followed by name=val. */ static int parsePseudoAttribute(const ENCODING *enc, const char *ptr, const char *end, const char **namePtr, const char **valPtr, const char **nextTokPtr) { int c; char open; if (ptr == end) { *namePtr = 0; return 1; } if (!isSpace(toAscii(enc, ptr, end))) { *nextTokPtr = ptr; return 0; } do { ptr += enc->minBytesPerChar; } while (isSpace(toAscii(enc, ptr, end))); if (ptr == end) { *namePtr = 0; return 1; } *namePtr = ptr; for (;;) { c = toAscii(enc, ptr, end); if (c == -1) { *nextTokPtr = ptr; return 0; } if (c == '=') break; if (isSpace(c)) { do { ptr += enc->minBytesPerChar; } while (isSpace(c = toAscii(enc, ptr, end))); if (c != '=') { *nextTokPtr = ptr; return 0; } break; } ptr += enc->minBytesPerChar; } if (ptr == *namePtr) { *nextTokPtr = ptr; return 0; } ptr += enc->minBytesPerChar; c = toAscii(enc, ptr, end); while (isSpace(c)) { ptr += enc->minBytesPerChar; c = toAscii(enc, ptr, end); } if (c != '"' && c != '\'') { *nextTokPtr = ptr; return 0; } open = c; ptr += enc->minBytesPerChar; *valPtr = ptr; for (;; ptr += enc->minBytesPerChar) { c = toAscii(enc, ptr, end); if (c == open) break; if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') && !('0' <= c && c <= '9') && c != '.' && c != '-' && c != '_') { *nextTokPtr = ptr; return 0; } } *nextTokPtr = ptr + enc->minBytesPerChar; return 1; } static int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *, const char *, const char *), int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **encodingName, const ENCODING **encoding, int *standalone) { const char *val = 0; const char *name = 0; ptr += 5 * enc->minBytesPerChar; end -= 2 * enc->minBytesPerChar; if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr) || !name) { *badPtr = ptr; return 0; } if (!XmlNameMatchesAscii(enc, name, "version")) { if (!isGeneralTextEntity) { *badPtr = name; return 0; } } else { if (versionPtr) *versionPtr = val; if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) { *badPtr = ptr; return 0; } if (!name) { if (isGeneralTextEntity) { /* a TextDecl must have an EncodingDecl */ *badPtr = ptr; return 0; } return 1; } } if (XmlNameMatchesAscii(enc, name, "encoding")) { int c = toAscii(enc, val, end); if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z')) { *badPtr = val; return 0; } if (encodingName) *encodingName = val; if (encoding) *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar); if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) { *badPtr = ptr; return 0; } if (!name) return 1; } if (!XmlNameMatchesAscii(enc, name, "standalone") || isGeneralTextEntity) { *badPtr = name; return 0; } if (XmlNameMatchesAscii(enc, val, "yes")) { if (standalone) *standalone = 1; } else if (XmlNameMatchesAscii(enc, val, "no")) { if (standalone) *standalone = 0; } else { *badPtr = val; return 0; } while (isSpace(toAscii(enc, ptr, end))) ptr += enc->minBytesPerChar; if (ptr != end) { *badPtr = ptr; return 0; } return 1; } static int checkCharRefNumber(int result) { switch (result >> 8) { case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE: case 0xDF: return -1; case 0: if (latin1_encoding.type[result] == BT_NONXML) return -1; break; case 0xFF: if (result == 0xFFFE || result == 0xFFFF) return -1; break; } return result; } int XmlUtf8Encode(int c, char *buf) { enum { /* minN is minimum legal resulting value for N byte sequence */ min2 = 0x80, min3 = 0x800, min4 = 0x10000 }; if (c < 0) return 0; if (c < min2) { buf[0] = (c | UTF8_cval1); return 1; } if (c < min3) { buf[0] = ((c >> 6) | UTF8_cval2); buf[1] = ((c & 0x3f) | 0x80); return 2; } if (c < min4) { buf[0] = ((c >> 12) | UTF8_cval3); buf[1] = (((c >> 6) & 0x3f) | 0x80); buf[2] = ((c & 0x3f) | 0x80); return 3; } if (c < 0x110000) { buf[0] = ((c >> 18) | UTF8_cval4); buf[1] = (((c >> 12) & 0x3f) | 0x80); buf[2] = (((c >> 6) & 0x3f) | 0x80); buf[3] = ((c & 0x3f) | 0x80); return 4; } return 0; } int XmlUtf16Encode(int charNum, unsigned short *buf) { if (charNum < 0) return 0; if (charNum < 0x10000) { buf[0] = charNum; return 1; } if (charNum < 0x110000) { charNum -= 0x10000; buf[0] = (charNum >> 10) + 0xD800; buf[1] = (charNum & 0x3FF) + 0xDC00; return 2; } return 0; } struct unknown_encoding { struct normal_encoding normal; int (*convert)(void *userData, const char *p); void *userData; unsigned short utf16[256]; char utf8[256][4]; }; int XmlSizeOfUnknownEncoding(void) { return sizeof(struct unknown_encoding); } static int unknown_isName(const ENCODING *enc, const char *p) { int c = ((const struct unknown_encoding *)enc) ->convert(((const struct unknown_encoding *)enc)->userData, p); if (c & ~0xFFFF) return 0; return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF); } static int unknown_isNmstrt(const ENCODING *enc, const char *p) { int c = ((const struct unknown_encoding *)enc) ->convert(((const struct unknown_encoding *)enc)->userData, p); if (c & ~0xFFFF) return 0; return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF); } static int unknown_isInvalid(const ENCODING *enc, const char *p) { int c = ((const struct unknown_encoding *)enc) ->convert(((const struct unknown_encoding *)enc)->userData, p); return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; } static void unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) { char buf[XML_UTF8_ENCODE_MAX]; for (;;) { const char *utf8; int n; if (*fromP == fromLim) break; utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP]; n = *utf8++; if (n == 0) { int c = ((const struct unknown_encoding *)enc) ->convert(((const struct unknown_encoding *)enc)->userData, *fromP); n = XmlUtf8Encode(c, buf); if (n > toLim - *toP) break; utf8 = buf; *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2); } else { if (n > toLim - *toP) break; (*fromP)++; } do { *(*toP)++ = *utf8++; } while (--n != 0); } } static void unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { while (*fromP != fromLim && *toP != toLim) { unsigned short c = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP]; if (c == 0) { c = (unsigned short)((const struct unknown_encoding *)enc) ->convert(((const struct unknown_encoding *)enc)->userData, *fromP); *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2); } else (*fromP)++; *(*toP)++ = c; } } ENCODING * XmlInitUnknownEncoding(void *mem, int *table, int (*convert)(void *userData, const char *p), void *userData) { int i; struct unknown_encoding *e = mem; for (i = 0; i < sizeof(struct normal_encoding); i++) ((char *)mem)[i] = ((char *)&latin1_encoding)[i]; for (i = 0; i < 128; i++) if (latin1_encoding.type[i] != BT_OTHER && latin1_encoding.type[i] != BT_NONXML && table[i] != i) return 0; for (i = 0; i < 256; i++) { int c = table[i]; if (c == -1) { e->normal.type[i] = BT_MALFORM; /* This shouldn't really get used. */ e->utf16[i] = 0xFFFF; e->utf8[i][0] = 1; e->utf8[i][1] = 0; } else if (c < 0) { if (c < -4) return 0; e->normal.type[i] = BT_LEAD2 - (c + 2); e->utf8[i][0] = 0; e->utf16[i] = 0; } else if (c < 0x80) { if (latin1_encoding.type[c] != BT_OTHER && latin1_encoding.type[c] != BT_NONXML && c != i) return 0; e->normal.type[i] = latin1_encoding.type[c]; e->utf8[i][0] = 1; e->utf8[i][1] = (char)c; e->utf16[i] = c == 0 ? 0xFFFF : c; } else if (checkCharRefNumber(c) < 0) { e->normal.type[i] = BT_NONXML; /* This shouldn't really get used. */ e->utf16[i] = 0xFFFF; e->utf8[i][0] = 1; e->utf8[i][1] = 0; } else { if (c > 0xFFFF) return 0; if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff)) e->normal.type[i] = BT_NMSTRT; else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff)) e->normal.type[i] = BT_NAME; else e->normal.type[i] = BT_OTHER; e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1); e->utf16[i] = c; } } e->userData = userData; e->convert = convert; if (convert) { e->normal.isName2 = unknown_isName; e->normal.isName3 = unknown_isName; e->normal.isName4 = unknown_isName; e->normal.isNmstrt2 = unknown_isNmstrt; e->normal.isNmstrt3 = unknown_isNmstrt; e->normal.isNmstrt4 = unknown_isNmstrt; e->normal.isInvalid2 = unknown_isInvalid; e->normal.isInvalid3 = unknown_isInvalid; e->normal.isInvalid4 = unknown_isInvalid; } e->normal.enc.utf8Convert = unknown_toUtf8; e->normal.enc.utf16Convert = unknown_toUtf16; return &(e->normal.enc); } /* If this enumeration is changed, getEncodingIndex and encodings must also be changed. */ enum { UNKNOWN_ENC = -1, ISO_8859_1_ENC = 0, US_ASCII_ENC, UTF_8_ENC, UTF_16_ENC, UTF_16BE_ENC, UTF_16LE_ENC, /* must match encodingNames up to here */ NO_ENC }; static int getEncodingIndex(const char *name) { static const char *encodingNames[] = { "ISO-8859-1", "US-ASCII", "UTF-8", "UTF-16", "UTF-16BE" "UTF-16LE", }; int i; if (name == 0) return NO_ENC; for (i = 0; i < sizeof(encodingNames)/sizeof(encodingNames[0]); i++) if (streqci(name, encodingNames[i])) return i; return UNKNOWN_ENC; } /* For binary compatibility, we store the index of the encoding specified at initialization in the isUtf16 member. */ #define INIT_ENC_INDEX(enc) ((enc)->initEnc.isUtf16) /* This is what detects the encoding. encodingTable maps from encoding indices to encodings; INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding; state is XML_CONTENT_STATE if we're parsing an external text entity, and XML_PROLOG_STATE otherwise. */ static int initScan(const ENCODING **encodingTable, const INIT_ENCODING *enc, int state, const char *ptr, const char *end, const char **nextTokPtr) { const ENCODING **encPtr; if (ptr == end) return XML_TOK_NONE; encPtr = enc->encPtr; if (ptr + 1 == end) { /* only a single byte available for auto-detection */ /* a well-formed document entity must have more than one byte */ if (state != XML_CONTENT_STATE) return XML_TOK_PARTIAL; /* so we're parsing an external text entity... */ /* if UTF-16 was externally specified, then we need at least 2 bytes */ switch (INIT_ENC_INDEX(enc)) { case UTF_16_ENC: case UTF_16LE_ENC: case UTF_16BE_ENC: return XML_TOK_PARTIAL; } switch ((unsigned char)*ptr) { case 0xFE: case 0xFF: case 0xEF: /* possibly first byte of UTF-8 BOM */ if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; /* fall through */ case 0x00: case 0x3C: return XML_TOK_PARTIAL; } } else { switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) { case 0xFEFF: if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; *nextTokPtr = ptr + 2; *encPtr = encodingTable[UTF_16BE_ENC]; return XML_TOK_BOM; /* 00 3C is handled in the default case */ case 0x3C00: if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC || INIT_ENC_INDEX(enc) == UTF_16_ENC) && state == XML_CONTENT_STATE) break; *encPtr = encodingTable[UTF_16LE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); case 0xFFFE: if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC && state == XML_CONTENT_STATE) break; *nextTokPtr = ptr + 2; *encPtr = encodingTable[UTF_16LE_ENC]; return XML_TOK_BOM; case 0xEFBB: /* Maybe a UTF-8 BOM (EF BB BF) */ /* If there's an explicitly specified (external) encoding of ISO-8859-1 or some flavour of UTF-16 and this is an external text entity, don't look for the BOM, because it might be a legal data. */ if (state == XML_CONTENT_STATE) { int e = INIT_ENC_INDEX(enc); if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC) break; } if (ptr + 2 == end) return XML_TOK_PARTIAL; if ((unsigned char)ptr[2] == 0xBF) { *encPtr = encodingTable[UTF_8_ENC]; return XML_TOK_BOM; } break; default: if (ptr[0] == '\0') { /* 0 isn't a legal data character. Furthermore a document entity can only start with ASCII characters. So the only way this can fail to be big-endian UTF-16 if it it's an external parsed general entity that's labelled as UTF-16LE. */ if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC) break; *encPtr = encodingTable[UTF_16BE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } else if (ptr[1] == '\0') { /* We could recover here in the case: - parsing an external entity - second byte is 0 - no externally specified encoding - no encoding declaration by assuming UTF-16LE. But we don't, because this would mean when presented just with a single byte, we couldn't reliably determine whether we needed further bytes. */ if (state == XML_CONTENT_STATE) break; *encPtr = encodingTable[UTF_16LE_ENC]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } break; } } *encPtr = encodingTable[(int)INIT_ENC_INDEX(enc)]; return XmlTok(*encPtr, state, ptr, end, nextTokPtr); } #define NS(x) x #define ns(x) x #include "xmltok_ns.c" #undef NS #undef ns #ifdef XML_NS #define NS(x) x ## NS #define ns(x) x ## _ns #include "xmltok_ns.c" #undef NS #undef ns ENCODING * XmlInitUnknownEncodingNS(void *mem, int *table, int (*convert)(void *userData, const char *p), void *userData) { ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData); if (enc) ((struct normal_encoding *)enc)->type[':'] = BT_COLON; return enc; } #endif /* XML_NS */ 1.1 apache-apr/pthreads/src/lib/expat-lite/xmltok.h Index: xmltok.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #ifndef XmlTok_INCLUDED #define XmlTok_INCLUDED 1 #ifdef __cplusplus extern "C" { #endif #ifndef XMLTOKAPI #define XMLTOKAPI /* as nothing */ #endif /* The following token may be returned by XmlContentTok */ #define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of illegal ]]> sequence */ /* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ #define XML_TOK_NONE -4 /* The string to be scanned is empty */ #define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan; might be part of CRLF sequence */ #define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */ #define XML_TOK_PARTIAL -1 /* only part of a token */ #define XML_TOK_INVALID 0 /* The following tokens are returned by XmlContentTok; some are also returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */ #define XML_TOK_START_TAG_WITH_ATTS 1 #define XML_TOK_START_TAG_NO_ATTS 2 #define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */ #define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4 #define XML_TOK_END_TAG 5 #define XML_TOK_DATA_CHARS 6 #define XML_TOK_DATA_NEWLINE 7 #define XML_TOK_CDATA_SECT_OPEN 8 #define XML_TOK_ENTITY_REF 9 #define XML_TOK_CHAR_REF 10 /* numeric character reference */ /* The following tokens may be returned by both XmlPrologTok and XmlContentTok */ #define XML_TOK_PI 11 /* processing instruction */ #define XML_TOK_XML_DECL 12 /* XML decl or text decl */ #define XML_TOK_COMMENT 13 #define XML_TOK_BOM 14 /* Byte order mark */ /* The following tokens are returned only by XmlPrologTok */ #define XML_TOK_PROLOG_S 15 #define XML_TOK_DECL_OPEN 16 /* <!foo */ #define XML_TOK_DECL_CLOSE 17 /* > */ #define XML_TOK_NAME 18 #define XML_TOK_NMTOKEN 19 #define XML_TOK_POUND_NAME 20 /* #name */ #define XML_TOK_OR 21 /* | */ #define XML_TOK_PERCENT 22 #define XML_TOK_OPEN_PAREN 23 #define XML_TOK_CLOSE_PAREN 24 #define XML_TOK_OPEN_BRACKET 25 #define XML_TOK_CLOSE_BRACKET 26 #define XML_TOK_LITERAL 27 #define XML_TOK_PARAM_ENTITY_REF 28 #define XML_TOK_INSTANCE_START 29 /* The following occur only in element type declarations */ #define XML_TOK_NAME_QUESTION 30 /* name? */ #define XML_TOK_NAME_ASTERISK 31 /* name* */ #define XML_TOK_NAME_PLUS 32 /* name+ */ #define XML_TOK_COND_SECT_OPEN 33 /* <![ */ #define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */ #define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */ #define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */ #define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */ #define XML_TOK_COMMA 38 /* The following token is returned only by XmlAttributeValueTok */ #define XML_TOK_ATTRIBUTE_VALUE_S 39 /* The following token is returned only by XmlCdataSectionTok */ #define XML_TOK_CDATA_SECT_CLOSE 40 /* With namespace processing this is returned by XmlPrologTok for a name with a colon. */ #define XML_TOK_PREFIXED_NAME 41 #define XML_N_STATES 3 #define XML_PROLOG_STATE 0 #define XML_CONTENT_STATE 1 #define XML_CDATA_SECTION_STATE 2 #define XML_N_LITERAL_TYPES 2 #define XML_ATTRIBUTE_VALUE_LITERAL 0 #define XML_ENTITY_VALUE_LITERAL 1 /* The size of the buffer passed to XmlUtf8Encode must be at least this. */ #define XML_UTF8_ENCODE_MAX 4 /* The size of the buffer passed to XmlUtf16Encode must be at least this. */ #define XML_UTF16_ENCODE_MAX 2 typedef struct position { /* first line and first column are 0 not 1 */ unsigned long lineNumber; unsigned long columnNumber; } POSITION; typedef struct { const char *name; const char *valuePtr; const char *valueEnd; char normalized; } ATTRIBUTE; struct encoding; typedef struct encoding ENCODING; struct encoding { int (*scanners[XML_N_STATES])(const ENCODING *, const char *, const char *, const char **); int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *, const char *, const char *, const char **); int (*sameName)(const ENCODING *, const char *, const char *); int (*nameMatchesAscii)(const ENCODING *, const char *, const char *); int (*nameLength)(const ENCODING *, const char *); const char *(*skipS)(const ENCODING *, const char *); int (*getAtts)(const ENCODING *enc, const char *ptr, int attsMax, ATTRIBUTE *atts); int (*charRefNumber)(const ENCODING *enc, const char *ptr); int (*predefinedEntityName)(const ENCODING *, const char *, const char *); void (*updatePosition)(const ENCODING *, const char *ptr, const char *end, POSITION *); int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr); void (*utf8Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim); void (*utf16Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim); int minBytesPerChar; char isUtf8; char isUtf16; }; /* Scan the string starting at ptr until the end of the next complete token, but do not scan past eptr. Return an integer giving the type of token. Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set. Return XML_TOK_PARTIAL when the string does not contain a complete token; nextTokPtr will not be set. Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr will be set to point to the character which made the token invalid. Otherwise the string starts with a valid token; nextTokPtr will be set to point to the character following the end of that token. Each data character counts as a single token, but adjacent data characters may be returned together. Similarly for characters in the prolog outside literals, comments and processing instructions. */ #define XmlTok(enc, state, ptr, end, nextTokPtr) \ (((enc)->scanners[state])(enc, ptr, end, nextTokPtr)) #define XmlPrologTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr) #define XmlContentTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr) #define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \ XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr) /* This is used for performing a 2nd-level tokenization on the content of a literal that has already been returned by XmlTok. */ #define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \ (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr)) #define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \ XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr) #define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \ XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr) #define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2)) #define XmlNameMatchesAscii(enc, ptr1, ptr2) \ (((enc)->nameMatchesAscii)(enc, ptr1, ptr2)) #define XmlNameLength(enc, ptr) \ (((enc)->nameLength)(enc, ptr)) #define XmlSkipS(enc, ptr) \ (((enc)->skipS)(enc, ptr)) #define XmlGetAttributes(enc, ptr, attsMax, atts) \ (((enc)->getAtts)(enc, ptr, attsMax, atts)) #define XmlCharRefNumber(enc, ptr) \ (((enc)->charRefNumber)(enc, ptr)) #define XmlPredefinedEntityName(enc, ptr, end) \ (((enc)->predefinedEntityName)(enc, ptr, end)) #define XmlUpdatePosition(enc, ptr, end, pos) \ (((enc)->updatePosition)(enc, ptr, end, pos)) #define XmlIsPublicId(enc, ptr, end, badPtr) \ (((enc)->isPublicId)(enc, ptr, end, badPtr)) #define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \ (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim)) #define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \ (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim)) typedef struct { ENCODING initEnc; const ENCODING **encPtr; } INIT_ENCODING; int XMLTOKAPI XmlParseXmlDecl(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **encodingNamePtr, const ENCODING **namedEncodingPtr, int *standalonePtr); int XMLTOKAPI XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name); const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding(void); const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding(void); int XMLTOKAPI XmlUtf8Encode(int charNumber, char *buf); int XMLTOKAPI XmlUtf16Encode(int charNumber, unsigned short *buf); int XMLTOKAPI XmlSizeOfUnknownEncoding(void); ENCODING XMLTOKAPI * XmlInitUnknownEncoding(void *mem, int *table, int (*conv)(void *userData, const char *p), void *userData); int XMLTOKAPI XmlParseXmlDeclNS(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **encodingNamePtr, const ENCODING **namedEncodingPtr, int *standalonePtr); int XMLTOKAPI XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name); const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncodingNS(void); const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncodingNS(void); ENCODING XMLTOKAPI * XmlInitUnknownEncodingNS(void *mem, int *table, int (*conv)(void *userData, const char *p), void *userData); #ifdef __cplusplus } #endif #endif /* not XmlTok_INCLUDED */ 1.1 apache-apr/pthreads/src/lib/expat-lite/xmltok_impl.c Index: xmltok_impl.c =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ #ifndef IS_INVALID_CHAR #define IS_INVALID_CHAR(enc, ptr, n) (0) #endif #define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \ case BT_LEAD ## n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_INVALID_CHAR(enc, ptr, n)) { \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; #define INVALID_CASES(ptr, nextTokPtr) \ INVALID_LEAD_CASE(2, ptr, nextTokPtr) \ INVALID_LEAD_CASE(3, ptr, nextTokPtr) \ INVALID_LEAD_CASE(4, ptr, nextTokPtr) \ case BT_NONXML: \ case BT_MALFORM: \ case BT_TRAIL: \ *(nextTokPtr) = (ptr); \ return XML_TOK_INVALID; #define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \ case BT_LEAD ## n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (!IS_NAME_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; #define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \ case BT_NONASCII: \ if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ case BT_NMSTRT: \ case BT_HEX: \ case BT_DIGIT: \ case BT_NAME: \ case BT_MINUS: \ ptr += MINBPC(enc); \ break; \ CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \ CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \ CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr) #define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \ case BT_LEAD ## n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ ptr += n; \ break; #define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \ case BT_NONASCII: \ if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; \ } \ case BT_NMSTRT: \ case BT_HEX: \ ptr += MINBPC(enc); \ break; \ CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \ CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \ CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr) #ifndef PREFIX #define PREFIX(ident) ident #endif /* ptr points to character following "<!-" */ static int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr != end) { if (!CHAR_MATCHES(enc, ptr, '-')) { *nextTokPtr = ptr; return XML_TOK_INVALID; } ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_MINUS: if ((ptr += MINBPC(enc)) == end) return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, '-')) { if ((ptr += MINBPC(enc)) == end) return XML_TOK_PARTIAL; if (!CHAR_MATCHES(enc, ptr, '>')) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_COMMENT; } break; default: ptr += MINBPC(enc); break; } } } return XML_TOK_PARTIAL; } /* ptr points to character following "<!" */ static int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { case BT_MINUS: return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_LSQB: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_COND_SECT_OPEN; case BT_NMSTRT: case BT_HEX: ptr += MINBPC(enc); break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { case BT_PERCNT: if (ptr + MINBPC(enc) == end) return XML_TOK_PARTIAL; /* don't allow <!ENTITY% foo "whatever"> */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_INVALID; } /* fall through */ case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DECL_OPEN; case BT_NMSTRT: case BT_HEX: ptr += MINBPC(enc); break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr) { int upper = 0; *tokPtr = XML_TOK_PI; if (end - ptr != MINBPC(enc)*3) return 1; switch (BYTE_TO_ASCII(enc, ptr)) { case 'x': break; case 'X': upper = 1; break; default: return 1; } ptr += MINBPC(enc); switch (BYTE_TO_ASCII(enc, ptr)) { case 'm': break; case 'M': upper = 1; break; default: return 1; } ptr += MINBPC(enc); switch (BYTE_TO_ASCII(enc, ptr)) { case 'l': break; case 'L': upper = 1; break; default: return 1; } if (upper) return 0; *tokPtr = XML_TOK_XML_DECL; return 1; } /* ptr points to character following "<?" */ static int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { int tok; const char *target = ptr; if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { *nextTokPtr = ptr; return XML_TOK_INVALID; } ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_QUEST: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, '>')) { *nextTokPtr = ptr + MINBPC(enc); return tok; } break; default: ptr += MINBPC(enc); break; } } return XML_TOK_PARTIAL; case BT_QUEST: if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) { *nextTokPtr = ptr; return XML_TOK_INVALID; } ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, '>')) { *nextTokPtr = ptr + MINBPC(enc); return tok; } /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { int i; /* CDATA[ */ if (end - ptr < 6 * MINBPC(enc)) return XML_TOK_PARTIAL; for (i = 0; i < 6; i++, ptr += MINBPC(enc)) { if (!CHAR_MATCHES(enc, ptr, "CDATA["[i])) { *nextTokPtr = ptr; return XML_TOK_INVALID; } } *nextTokPtr = ptr; return XML_TOK_CDATA_SECT_OPEN; } static int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr == end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_RSQB: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; if (!CHAR_MATCHES(enc, ptr, ']')) break; ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; if (!CHAR_MATCHES(enc, ptr, '>')) { ptr -= MINBPC(enc); break; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CDATA_SECT_CLOSE; case BT_CR: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; INVALID_CASES(ptr, nextTokPtr) default: ptr += MINBPC(enc); break; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_DATA_CHARS; \ } \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NONXML: case BT_MALFORM: case BT_TRAIL: case BT_CR: case BT_LF: case BT_RSQB: *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } /* ptr points to character following "</" */ static int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: break; case BT_GT: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_END_TAG; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; #ifdef XML_NS case BT_COLON: /* no need to check qname syntax here, since end-tag must match exactly */ ptr += MINBPC(enc); break; #endif case BT_GT: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_END_TAG; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } /* ptr points to character following "&#X" */ static int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: break; case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CHAR_REF; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } } return XML_TOK_PARTIAL; } /* ptr points to character following "&#" */ static int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr != end) { if (CHAR_MATCHES(enc, ptr, 'x')) return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: break; case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CHAR_REF; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } } return XML_TOK_PARTIAL; } /* ptr points to character following "&" */ static int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_NUM: return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_ENTITY_REF; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } /* ptr points to character following first character of attribute name */ static int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { #ifdef XML_NS int hadColon = 0; #endif while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) #ifdef XML_NS case BT_COLON: if (hadColon) { *nextTokPtr = ptr; return XML_TOK_INVALID; } hadColon = 1; ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } break; #endif case BT_S: case BT_CR: case BT_LF: for (;;) { int t; ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; t = BYTE_TYPE(enc, ptr); if (t == BT_EQUALS) break; switch (t) { case BT_S: case BT_LF: case BT_CR: break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } /* fall through */ case BT_EQUALS: { int open; #ifdef XML_NS hadColon = 0; #endif for (;;) { ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; open = BYTE_TYPE(enc, ptr); if (open == BT_QUOT || open == BT_APOS) break; switch (open) { case BT_S: case BT_LF: case BT_CR: break; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } ptr += MINBPC(enc); /* in attribute value */ for (;;) { int t; if (ptr == end) return XML_TOK_PARTIAL; t = BYTE_TYPE(enc, ptr); if (t == open) break; switch (t) { INVALID_CASES(ptr, nextTokPtr) case BT_AMP: { int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr); if (tok <= 0) { if (tok == XML_TOK_INVALID) *nextTokPtr = ptr; return tok; } break; } case BT_LT: *nextTokPtr = ptr; return XML_TOK_INVALID; default: ptr += MINBPC(enc); break; } } ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: break; case BT_SOL: goto sol; case BT_GT: goto gt; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } /* ptr points to closing quote */ for (;;) { ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: continue; case BT_GT: gt: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_START_TAG_WITH_ATTS; case BT_SOL: sol: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; if (!CHAR_MATCHES(enc, ptr, '>')) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_EMPTY_ELEMENT_WITH_ATTS; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } break; } break; } default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } /* ptr points to character following "<" */ static int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { #ifdef XML_NS int hadColon; #endif if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_EXCL: if ((ptr += MINBPC(enc)) == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { case BT_MINUS: return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_LSQB: return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr); } *nextTokPtr = ptr; return XML_TOK_INVALID; case BT_QUEST: return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_SOL: return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr); default: *nextTokPtr = ptr; return XML_TOK_INVALID; } #ifdef XML_NS hadColon = 0; #endif /* we have a start-tag */ while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) #ifdef XML_NS case BT_COLON: if (hadColon) { *nextTokPtr = ptr; return XML_TOK_INVALID; } hadColon = 1; ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } break; #endif case BT_S: case BT_CR: case BT_LF: { ptr += MINBPC(enc); while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_GT: goto gt; case BT_SOL: goto sol; case BT_S: case BT_CR: case BT_LF: ptr += MINBPC(enc); continue; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr); } return XML_TOK_PARTIAL; } case BT_GT: gt: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_START_TAG_NO_ATTS; case BT_SOL: sol: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; if (!CHAR_MATCHES(enc, ptr, '>')) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_EMPTY_ELEMENT_NO_ATTS; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr == end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_LT: return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_AMP: return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_CR: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; case BT_LF: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; case BT_RSQB: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_TRAILING_RSQB; if (!CHAR_MATCHES(enc, ptr, ']')) break; ptr += MINBPC(enc); if (ptr == end) return XML_TOK_TRAILING_RSQB; if (!CHAR_MATCHES(enc, ptr, '>')) { ptr -= MINBPC(enc); break; } *nextTokPtr = ptr; return XML_TOK_INVALID; INVALID_CASES(ptr, nextTokPtr) default: ptr += MINBPC(enc); break; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \ if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \ *nextTokPtr = ptr; \ return XML_TOK_DATA_CHARS; \ } \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_RSQB: if (ptr + MINBPC(enc) != end) { if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ']')) { ptr += MINBPC(enc); break; } if (ptr + 2*MINBPC(enc) != end) { if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), '>')) { ptr += MINBPC(enc); break; } *nextTokPtr = ptr + 2*MINBPC(enc); return XML_TOK_INVALID; } } /* fall through */ case BT_AMP: case BT_LT: case BT_NONXML: case BT_MALFORM: case BT_TRAIL: case BT_CR: case BT_LF: *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } /* ptr points to character following "%" */ static int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: *nextTokPtr = ptr; return XML_TOK_PERCENT; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_PARAM_ENTITY_REF; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S: case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR: *nextTokPtr = ptr; return XML_TOK_POUND_NAME; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { while (ptr != end) { int t = BYTE_TYPE(enc, ptr); switch (t) { INVALID_CASES(ptr, nextTokPtr) case BT_QUOT: case BT_APOS: ptr += MINBPC(enc); if (t != open) break; if (ptr == end) return XML_TOK_PARTIAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: case BT_GT: case BT_PERCNT: case BT_LSQB: return XML_TOK_LITERAL; default: return XML_TOK_INVALID; } default: ptr += MINBPC(enc); break; } } return XML_TOK_PARTIAL; } static int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { int tok; if (ptr == end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; if (n & (MINBPC(enc) - 1)) { n &= ~(MINBPC(enc) - 1); if (n == 0) return XML_TOK_PARTIAL; end = ptr + n; } } switch (BYTE_TYPE(enc, ptr)) { case BT_QUOT: return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_APOS: return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_LT: { ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { case BT_EXCL: return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_QUEST: return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_NMSTRT: case BT_HEX: case BT_NONASCII: case BT_LEAD2: case BT_LEAD3: case BT_LEAD4: *nextTokPtr = ptr - MINBPC(enc); return XML_TOK_INSTANCE_START; } *nextTokPtr = ptr; return XML_TOK_INVALID; } case BT_CR: if (ptr + MINBPC(enc) == end) return XML_TOK_TRAILING_CR; /* fall through */ case BT_S: case BT_LF: for (;;) { ptr += MINBPC(enc); if (ptr == end) break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF: break; case BT_CR: /* don't split CR/LF pair */ if (ptr + MINBPC(enc) != end) break; /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_PROLOG_S; } } *nextTokPtr = ptr; return XML_TOK_PROLOG_S; case BT_PERCNT: return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_COMMA: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_COMMA; case BT_LSQB: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OPEN_BRACKET; case BT_RSQB: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr, ']')) { if (ptr + MINBPC(enc) == end) return XML_TOK_PARTIAL; if (CHAR_MATCHES(enc, ptr + MINBPC(enc), '>')) { *nextTokPtr = ptr + 2*MINBPC(enc); return XML_TOK_COND_SECT_CLOSE; } } *nextTokPtr = ptr; return XML_TOK_CLOSE_BRACKET; case BT_LPAR: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OPEN_PAREN; case BT_RPAR: ptr += MINBPC(enc); if (ptr == end) return XML_TOK_PARTIAL; switch (BYTE_TYPE(enc, ptr)) { case BT_AST: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_ASTERISK; case BT_QUEST: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_QUESTION; case BT_PLUS: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_CLOSE_PAREN_PLUS; case BT_CR: case BT_LF: case BT_S: case BT_GT: case BT_COMMA: case BT_VERBAR: case BT_RPAR: *nextTokPtr = ptr; return XML_TOK_CLOSE_PAREN; } *nextTokPtr = ptr; return XML_TOK_INVALID; case BT_VERBAR: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_OR; case BT_GT: *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DECL_CLOSE; case BT_NUM: return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr); #define LEAD_CASE(n) \ case BT_LEAD ## n: \ if (end - ptr < n) \ return XML_TOK_PARTIAL_CHAR; \ if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ ptr += n; \ tok = XML_TOK_NAME; \ break; \ } \ if (IS_NAME_CHAR(enc, ptr, n)) { \ ptr += n; \ tok = XML_TOK_NMTOKEN; \ break; \ } \ *nextTokPtr = ptr; \ return XML_TOK_INVALID; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NMSTRT: case BT_HEX: tok = XML_TOK_NAME; ptr += MINBPC(enc); break; case BT_DIGIT: case BT_NAME: case BT_MINUS: #ifdef XML_NS case BT_COLON: #endif tok = XML_TOK_NMTOKEN; ptr += MINBPC(enc); break; case BT_NONASCII: if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { ptr += MINBPC(enc); tok = XML_TOK_NAME; break; } if (IS_NAME_CHAR_MINBPC(enc, ptr)) { ptr += MINBPC(enc); tok = XML_TOK_NMTOKEN; break; } /* fall through */ default: *nextTokPtr = ptr; return XML_TOK_INVALID; } while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_GT: case BT_RPAR: case BT_COMMA: case BT_VERBAR: case BT_LSQB: case BT_PERCNT: case BT_S: case BT_CR: case BT_LF: *nextTokPtr = ptr; return tok; #ifdef XML_NS case BT_COLON: ptr += MINBPC(enc); switch (tok) { case XML_TOK_NAME: if (ptr == end) return XML_TOK_PARTIAL; tok = XML_TOK_PREFIXED_NAME; switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) default: tok = XML_TOK_NMTOKEN; break; } break; case XML_TOK_PREFIXED_NAME: tok = XML_TOK_NMTOKEN; break; } break; #endif case BT_PLUS: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_PLUS; case BT_AST: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_ASTERISK; case BT_QUEST: if (tok == XML_TOK_NMTOKEN) { *nextTokPtr = ptr; return XML_TOK_INVALID; } *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_NAME_QUESTION; default: *nextTokPtr = ptr; return XML_TOK_INVALID; } } return XML_TOK_PARTIAL; } static int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { const char *start; if (ptr == end) return XML_TOK_NONE; start = ptr; while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_AMP: if (ptr == start) return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LT: /* this is for inside entity references */ *nextTokPtr = ptr; return XML_TOK_INVALID; case BT_LF: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { ptr += MINBPC(enc); if (ptr == end) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_S: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_ATTRIBUTE_VALUE_S; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } static int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { const char *start; if (ptr == end) return XML_TOK_NONE; start = ptr; while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_AMP: if (ptr == start) return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_PERCNT: if (ptr == start) return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr); *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_LF: if (ptr == start) { *nextTokPtr = ptr + MINBPC(enc); return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; case BT_CR: if (ptr == start) { ptr += MINBPC(enc); if (ptr == end) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; return XML_TOK_DATA_NEWLINE; } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; default: ptr += MINBPC(enc); break; } } *nextTokPtr = ptr; return XML_TOK_DATA_CHARS; } static int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, const char **badPtr) { ptr += MINBPC(enc); end -= MINBPC(enc); for (; ptr != end; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: case BT_MINUS: case BT_APOS: case BT_LPAR: case BT_RPAR: case BT_PLUS: case BT_COMMA: case BT_SOL: case BT_EQUALS: case BT_QUEST: case BT_CR: case BT_LF: case BT_SEMI: case BT_EXCL: case BT_AST: case BT_PERCNT: case BT_NUM: #ifdef XML_NS case BT_COLON: #endif break; case BT_S: if (CHAR_MATCHES(enc, ptr, '\t')) { *badPtr = ptr; return 0; } break; case BT_NAME: case BT_NMSTRT: if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f)) break; default: switch (BYTE_TO_ASCII(enc, ptr)) { case 0x24: /* $ */ case 0x40: /* @ */ break; default: *badPtr = ptr; return 0; } break; } } return 1; } /* This must only be called for a well-formed start-tag or empty element tag. Returns the number of attributes. Pointers to the first attsMax attributes are stored in atts. */ static int PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, ATTRIBUTE *atts) { enum { other, inName, inValue } state = inName; int nAtts = 0; int open = 0; for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { #define START_NAME \ if (state == other) { \ if (nAtts < attsMax) { \ atts[nAtts].name = ptr; \ atts[nAtts].normalized = 1; \ } \ state = inName; \ } #define LEAD_CASE(n) \ case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NONASCII: case BT_NMSTRT: case BT_HEX: START_NAME break; #undef START_NAME case BT_QUOT: if (state != inValue) { if (nAtts < attsMax) atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_QUOT; } else if (open == BT_QUOT) { state = other; if (nAtts < attsMax) atts[nAtts].valueEnd = ptr; nAtts++; } break; case BT_APOS: if (state != inValue) { if (nAtts < attsMax) atts[nAtts].valuePtr = ptr + MINBPC(enc); state = inValue; open = BT_APOS; } else if (open == BT_APOS) { state = other; if (nAtts < attsMax) atts[nAtts].valueEnd = ptr; nAtts++; } break; case BT_AMP: if (nAtts < attsMax) atts[nAtts].normalized = 0; break; case BT_S: if (state == inName) state = other; else if (state == inValue && nAtts < attsMax && atts[nAtts].normalized && (ptr == atts[nAtts].valuePtr || BYTE_TO_ASCII(enc, ptr) != ' ' || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ' ' || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open)) atts[nAtts].normalized = 0; break; case BT_CR: case BT_LF: /* This case ensures that the first attribute name is counted Apart from that we could just change state on the quote. */ if (state == inName) state = other; else if (state == inValue && nAtts < attsMax) atts[nAtts].normalized = 0; break; case BT_GT: case BT_SOL: if (state != inValue) return nAtts; break; default: break; } } /* not reached */ } static int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) { int result = 0; /* skip &# */ ptr += 2*MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 'x')) { for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ';'); ptr += MINBPC(enc)) { int c = BYTE_TO_ASCII(enc, ptr); switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': result <<= 4; result |= (c - '0'); break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': result <<= 4; result += 10 + (c - 'A'); break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': result <<= 4; result += 10 + (c - 'a'); break; } if (result >= 0x110000) return -1; } } else { for (; !CHAR_MATCHES(enc, ptr, ';'); ptr += MINBPC(enc)) { int c = BYTE_TO_ASCII(enc, ptr); result *= 10; result += (c - '0'); if (result >= 0x110000) return -1; } } return checkCharRefNumber(result); } static int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end) { switch ((end - ptr)/MINBPC(enc)) { case 2: if (CHAR_MATCHES(enc, ptr + MINBPC(enc), 't')) { switch (BYTE_TO_ASCII(enc, ptr)) { case 'l': return '<'; case 'g': return '>'; } } break; case 3: if (CHAR_MATCHES(enc, ptr, 'a')) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 'm')) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 'p')) return '&'; } } break; case 4: switch (BYTE_TO_ASCII(enc, ptr)) { case 'q': ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 'u')) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 'o')) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 't')) return '"'; } } break; case 'a': ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 'p')) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 'o')) { ptr += MINBPC(enc); if (CHAR_MATCHES(enc, ptr, 's')) return '\''; } } break; } } return 0; } static int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) { for (;;) { switch (BYTE_TYPE(enc, ptr1)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \ if (*ptr1++ != *ptr2++) \ return 0; LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2) #undef LEAD_CASE /* fall through */ if (*ptr1++ != *ptr2++) return 0; break; case BT_NONASCII: case BT_NMSTRT: #ifdef XML_NS case BT_COLON: #endif case BT_HEX: case BT_DIGIT: case BT_NAME: case BT_MINUS: if (*ptr2++ != *ptr1++) return 0; if (MINBPC(enc) > 1) { if (*ptr2++ != *ptr1++) return 0; if (MINBPC(enc) > 2) { if (*ptr2++ != *ptr1++) return 0; if (MINBPC(enc) > 3) { if (*ptr2++ != *ptr1++) return 0; } } } break; default: if (MINBPC(enc) == 1 && *ptr1 == *ptr2) return 1; switch (BYTE_TYPE(enc, ptr2)) { case BT_LEAD2: case BT_LEAD3: case BT_LEAD4: case BT_NONASCII: case BT_NMSTRT: #ifdef XML_NS case BT_COLON: #endif case BT_HEX: case BT_DIGIT: case BT_NAME: case BT_MINUS: return 0; default: return 1; } } } /* not reached */ } static int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, const char *ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { if (!CHAR_MATCHES(enc, ptr1, *ptr2)) return 0; } switch (BYTE_TYPE(enc, ptr1)) { case BT_LEAD2: case BT_LEAD3: case BT_LEAD4: case BT_NONASCII: case BT_NMSTRT: #ifdef XML_NS case BT_COLON: #endif case BT_HEX: case BT_DIGIT: case BT_NAME: case BT_MINUS: return 0; default: return 1; } } static int PREFIX(nameLength)(const ENCODING *enc, const char *ptr) { const char *start = ptr; for (;;) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_NONASCII: case BT_NMSTRT: #ifdef XML_NS case BT_COLON: #endif case BT_HEX: case BT_DIGIT: case BT_NAME: case BT_MINUS: ptr += MINBPC(enc); break; default: return ptr - start; } } } static const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr) { for (;;) { switch (BYTE_TYPE(enc, ptr)) { case BT_LF: case BT_CR: case BT_S: ptr += MINBPC(enc); break; default: return ptr; } } } static void PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, POSITION *pos) { while (ptr != end) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \ ptr += n; \ break; LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_LF: pos->columnNumber = (unsigned)-1; pos->lineNumber++; ptr += MINBPC(enc); break; case BT_CR: pos->lineNumber++; ptr += MINBPC(enc); if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); pos->columnNumber = (unsigned)-1; break; default: ptr += MINBPC(enc); break; } pos->columnNumber++; } } #undef DO_LEAD_CASE #undef MULTIBYTE_CASES #undef INVALID_CASES #undef CHECK_NAME_CASE #undef CHECK_NAME_CASES #undef CHECK_NMSTRT_CASE #undef CHECK_NMSTRT_CASES 1.1 apache-apr/pthreads/src/lib/expat-lite/xmltok_impl.h Index: xmltok_impl.h =================================================================== /* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is expat. The Initial Developer of the Original Code is James Clark. Portions created by James Clark are Copyright (C) 1998, 1999 James Clark. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of the GNU General Public License (the "GPL"), in which case the provisions of the GPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of the GPL and not to allow others to use your version of this file under the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. */ enum { BT_NONXML, BT_MALFORM, BT_LT, BT_AMP, BT_RSQB, BT_LEAD2, BT_LEAD3, BT_LEAD4, BT_TRAIL, BT_CR, BT_LF, BT_GT, BT_QUOT, BT_APOS, BT_EQUALS, BT_QUEST, BT_EXCL, BT_SOL, BT_SEMI, BT_NUM, BT_LSQB, BT_S, BT_NMSTRT, BT_COLON, BT_HEX, BT_DIGIT, BT_NAME, BT_MINUS, BT_OTHER, /* known not to be a name or name start character */ BT_NONASCII, /* might be a name or name start character */ BT_PERCNT, BT_LPAR, BT_RPAR, BT_AST, BT_PLUS, BT_COMMA, BT_VERBAR }; #include <stddef.h> 1.1 apache-apr/pthreads/src/lib/expat-lite/xmltok_ns.c Index: xmltok_ns.c =================================================================== const ENCODING *NS(XmlGetUtf8InternalEncoding)(void) { return &ns(internal_utf8_encoding).enc; } const ENCODING *NS(XmlGetUtf16InternalEncoding)(void) { #if XML_BYTE_ORDER == 12 return &ns(internal_little2_encoding).enc; #elif XML_BYTE_ORDER == 21 return &ns(internal_big2_encoding).enc; #else const short n = 1; return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc; #endif } static const ENCODING *NS(encodings)[] = { &ns(latin1_encoding).enc, &ns(ascii_encoding).enc, &ns(utf8_encoding).enc, &ns(big2_encoding).enc, &ns(big2_encoding).enc, &ns(little2_encoding).enc, &ns(utf8_encoding).enc /* NO_ENC */ }; static int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr); } static int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr); } int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name) { int i = getEncodingIndex(name); if (i == UNKNOWN_ENC) return 0; INIT_ENC_INDEX(p) = (char)i; p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog); p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent); p->initEnc.updatePosition = initUpdatePosition; p->encPtr = encPtr; *encPtr = &(p->initEnc); return 1; } static const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end) { #define ENCODING_MAX 128 char buf[ENCODING_MAX]; char *p = buf; int i; XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1); if (ptr != end) return 0; *p = 0; if (streqci(buf, "UTF-16") && enc->minBytesPerChar == 2) return enc; i = getEncodingIndex(buf); if (i == UNKNOWN_ENC) return 0; return NS(encodings)[i]; } int NS(XmlParseXmlDecl)(int isGeneralTextEntity, const ENCODING *enc, const char *ptr, const char *end, const char **badPtr, const char **versionPtr, const char **encodingName, const ENCODING **encoding, int *standalone) { return doParseXmlDecl(NS(findEncoding), isGeneralTextEntity, enc, ptr, end, badPtr, versionPtr, encodingName, encoding, standalone); } 1.10 +32 -0 apache-apr/pthreads/src/main/acceptlock.c Index: acceptlock.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/acceptlock.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -u -r1.9 -r1.10 --- acceptlock.c 1999/05/09 08:39:30 1.9 +++ acceptlock.c 1999/06/10 06:26:05 1.10 @@ -712,6 +712,38 @@ } } +#elif defined(USE_TPF_CORE_SERIALIZED_ACCEPT) + +static int tpf_core_held; + +static void accept_mutex_cleanup(void *foo) +{ + if(tpf_core_held) + coruc(RESOURCE_KEY); +} + +#define accept_mutex_init(x) + +static void accept_mutex_child_init(pool *p) +{ + ap_register_cleanup(p, NULL, accept_mutex_cleanup, ap_null_cleanup); + tpf_core_held = 0; +} + +static void accept_mutex_on(void) +{ + corhc(RESOURCE_KEY); + tpf_core_held = 1; + ap_check_signals(); +} + +static void accept_mutex_off(void) +{ + coruc(RESOURCE_KEY); + tpf_core_held = 0; + ap_check_signals(); +} + #else /* Default --- no serialization. Other methods *could* go here, * as #elifs... 1.8 +111 -1 apache-apr/pthreads/src/main/alloc.c Index: alloc.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/alloc.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -u -r1.7 -r1.8 --- alloc.c 1999/06/09 22:03:39 1.7 +++ alloc.c 1999/06/10 06:26:06 1.8 @@ -68,6 +68,11 @@ #include <stdarg.h> #include <pthread.h> +#ifdef OS2 +#define INCL_DOS +#include <os2.h> +#endif + /* debugging support, define this to enable code which helps detect re-use * of freed memory and other such nonsense. * @@ -111,6 +116,11 @@ */ /* #define MAKE_TABLE_PROFILE */ +/* Provide some statistics on the cost of allocations. It requires a + * bit of an understanding of how alloc.c works. + */ +/* #define ALLOC_STATS */ + #ifdef POOL_DEBUG #ifdef ALLOC_USE_MALLOC # error "sorry, no support for ALLOC_USE_MALLOC and POOL_DEBUG at the same time" @@ -206,6 +216,13 @@ static union block_hdr *global_block_list; #define FREE_POOL ((struct pool *)(-1)) #endif +#ifdef ALLOC_STATS +static unsigned long long num_free_blocks_calls; +static unsigned long long num_blocks_freed; +static unsigned max_blocks_in_one_free; +static unsigned num_malloc_calls; +static unsigned num_malloc_bytes; +#endif #ifdef ALLOC_DEBUG #define FILL_BYTE ((char)(0xa5)) @@ -243,6 +260,10 @@ */ size += CLICK_SZ; #endif +#ifdef ALLOC_STATS + ++num_malloc_calls; + num_malloc_bytes += size + sizeof(union block_hdr); +#endif blok = (union block_hdr *) malloc(size + sizeof(union block_hdr)); if (blok == NULL) { fprintf(stderr, "Ouch! malloc failed in malloc_block()\n"); @@ -309,6 +330,9 @@ free(blok); } #else +#ifdef ALLOC_STATS + unsigned num_blocks; +#endif /* First, put new blocks at the head of the free list --- * we'll eventually bash the 'next' pointer of the last block * in the chain to point to the free blocks we already had. @@ -329,7 +353,13 @@ * now. */ +#ifdef ALLOC_STATS + num_blocks = 1; +#endif while (blok->h.next != NULL) { +#ifdef ALLOC_STATS + ++num_blocks; +#endif reset_block(blok); blok = blok->h.next; } @@ -338,6 +368,15 @@ /* Finally, reset next pointer to get the old free blocks back */ blok->h.next = old_free_list; + +#ifdef ALLOC_STATS + if (num_blocks > max_blocks_in_one_free) { + max_blocks_in_one_free = num_blocks; + } + ++num_free_blocks_calls; + num_blocks_freed += num_blocks; +#endif + (void) pthread_mutex_unlock(&alloc_mutex); #endif } @@ -504,6 +543,20 @@ } #endif +#ifdef ALLOC_STATS +static void dump_stats(void) +{ + fprintf(stderr, + "alloc_stats: [%d] #free_blocks %llu #blocks %llu max %u #malloc %u #bytes %u\n", + (int)getpid(), + num_free_blocks_calls, + num_blocks_freed, + max_blocks_in_one_free, + num_malloc_calls, + num_malloc_bytes); +} +#endif + pool *ap_init_alloc(void) { #ifdef POOL_DEBUG @@ -513,6 +566,9 @@ stack_var_init(&s); #endif permanent_pool = ap_make_root_pool(); +#ifdef ALLOC_STATS + atexit(dump_stats); +#endif return permanent_pool; } @@ -2126,6 +2182,60 @@ */ } +#elif defined(OS2) + { + int save_in=-1, save_out=-1, save_err=-1; + + if (pipe_out) { + save_out = dup(STDOUT_FILENO); + dup2(out_fds[1], STDOUT_FILENO); + close(out_fds[1]); + DosSetFHState(out_fds[0], OPEN_FLAGS_NOINHERIT); + } + + if (pipe_in) { + save_in = dup(STDIN_FILENO); + dup2(in_fds[0], STDIN_FILENO); + close(in_fds[0]); + DosSetFHState(in_fds[1], OPEN_FLAGS_NOINHERIT); + } + + if (pipe_err) { + save_err = dup(STDERR_FILENO); + dup2(err_fds[1], STDERR_FILENO); + close(err_fds[1]); + DosSetFHState(err_fds[0], OPEN_FLAGS_NOINHERIT); + } + + pid = func(data, NULL); + + if ( pid ) + ap_note_subprocess(p, pid, kill_how); + + if (pipe_out) { + close(STDOUT_FILENO); + dup2(save_out, STDOUT_FILENO); + close(save_out); + *pipe_out = out_fds[0]; + } + + if (pipe_in) { + close(STDIN_FILENO); + dup2(save_in, STDIN_FILENO); + close(save_in); + *pipe_in = in_fds[1]; + } + + if (pipe_err) { + close(STDERR_FILENO); + dup2(save_err, STDERR_FILENO); + close(save_err); + *pipe_err = err_fds[0]; + } + } +#elif defined(TPF) + return (pid = ap_tpf_spawn_child(p, func, data, kill_how, + pipe_in, pipe_out, pipe_err, out_fds, in_fds, err_fds)); #else if ((pid = fork()) < 0) { @@ -2540,7 +2650,7 @@ if ((p->kill_how == kill_after_timeout) || (p->kill_how == kill_only_once)) { /* Subprocess may be dead already. Only need the timeout if not. */ - if (kill(p->pid, SIGTERM) != -1) + if (ap_os_kill(p->pid, SIGTERM) != -1) need_timeout = 1; } else if (p->kill_how == kill_always) { 1.18 +2 -2 apache-apr/pthreads/src/main/http_accept.c Index: http_accept.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_accept.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -u -r1.17 -r1.18 --- http_accept.c 1999/05/28 00:19:33 1.17 +++ http_accept.c 1999/06/10 06:26:07 1.18 @@ -155,7 +155,7 @@ break; } } else { - csd = accept(sd, &sa_client, &len); + csd = ap_accept(sd, &sa_client, &len); requests_this_child--; break; } @@ -442,7 +442,7 @@ got_lr: sd = lr->fd; } - csd = accept(sd, sa_client, &len); + csd = ap_accept(sd, sa_client, &len); requests_this_child--; if (csd >= 0) 1.13 +23 -15 apache-apr/pthreads/src/main/http_config.c Index: http_config.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_config.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -u -r1.12 -r1.13 --- http_config.c 1999/05/24 06:53:33 1.12 +++ http_config.c 1999/06/10 06:26:07 1.13 @@ -99,7 +99,7 @@ */ static int dynamic_modules = 0; API_VAR_EXPORT module *top_module = NULL; -API_VAR_EXPORT module **ap_loaded_modules; +API_VAR_EXPORT module **ap_loaded_modules=NULL; typedef int (*handler_func) (request_rec *); typedef void *(*dir_maker_func) (pool *, char *); @@ -960,8 +960,26 @@ return NULL; } +CORE_EXPORT(void *) ap_set_config_vectors(cmd_parms *parms, void *config, module *mod) +{ + void *mconfig = ap_get_module_config(config, mod); + void *sconfig = ap_get_module_config(parms->server->module_config, mod); + + if (!mconfig && mod->create_dir_config) { + mconfig = (*mod->create_dir_config) (parms->pool, parms->path); + ap_set_module_config(config, mod, mconfig); + } + + if (!sconfig && mod->create_server_config) { + sconfig = (*mod->create_server_config) (parms->pool, parms->server); + ap_set_module_config(parms->server->module_config, mod, sconfig); + } + return mconfig; +} + CORE_EXPORT(const char *) ap_handle_command(cmd_parms *parms, void *config, const char *l) { + void *oldconfig; const char *args, *cmd_name, *retval; const command_rec *cmd; module *mod = top_module; @@ -974,6 +992,8 @@ if (*cmd_name == '\0') return NULL; + oldconfig = parms->context; + parms->context = config; do { if (!(cmd = ap_find_command_in_modules(cmd_name, &mod))) { errno = EINVAL; @@ -982,25 +1002,13 @@ "not included in the server configuration", NULL); } else { - void *mconfig = ap_get_module_config(config, mod); - void *sconfig = - ap_get_module_config(parms->server->module_config, mod); - - if (!mconfig && mod->create_dir_config) { - mconfig = (*mod->create_dir_config) (parms->pool, parms->path); - ap_set_module_config(config, mod, mconfig); - } - - if (!sconfig && mod->create_server_config) { - sconfig = - (*mod->create_server_config) (parms->pool, parms->server); - ap_set_module_config(parms->server->module_config, mod, sconfig); - } + void *mconfig = ap_set_config_vectors(parms,config, mod); retval = invoke_cmd(cmd, parms, mconfig, args); mod = mod->next; /* Next time around, skip this one */ } } while (retval && !strcmp(retval, DECLINE_CMD)); + parms->context = oldconfig; return retval; } 1.14 +43 -28 apache-apr/pthreads/src/main/http_core.c Index: http_core.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_core.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -u -r1.13 -r1.14 --- http_core.c 1999/05/24 06:53:33 1.13 +++ http_core.c 1999/06/10 06:26:08 1.14 @@ -90,6 +90,9 @@ #endif #endif #endif +#ifndef MMAP_LIMIT +#define MMAP_LIMIT (4*1024*1024) +#endif /* Server core module... This module provides support for really basic * server operations, including options and commands which control the @@ -148,6 +151,9 @@ #ifdef WIN32 conf->script_interpreter_source = INTERPRETER_SOURCE_UNSET; #endif + + conf->server_signature = srv_sig_unset; + return (void *)conf; } @@ -271,6 +277,10 @@ } #endif + if (new->server_signature != srv_sig_unset) { + conf->server_signature = new->server_signature; + } + return (void*)conf; } @@ -333,7 +343,7 @@ *new_space = url_config; } -static void add_file_conf(core_dir_config *conf, void *url_config) +CORE_EXPORT(void) ap_add_file_conf(core_dir_config *conf, void *url_config) { void **new_space = (void **)ap_push_array(conf->sec); @@ -407,18 +417,16 @@ int nelts; void **elts; int i; + pool *tmp; - /* XXX: we are about to waste some ram ... we will build a new array - * and we need some scratch space to do it. The old array and the - * scratch space are never freed. - */ sconf = ap_get_module_config(s->module_config, &core_module); sec = sconf->sec; nelts = sec->nelts; elts = (void **)sec->elts; - /* build our sorting space */ - sortbin = ap_palloc(p, sec->nelts * sizeof(*sortbin)); + /* we have to allocate tmp space to do a stable sort */ + tmp = ap_make_sub_pool(p); + sortbin = ap_palloc(tmp, sec->nelts * sizeof(*sortbin)); for (i = 0; i < nelts; ++i) { sortbin[i].orig_index = i; sortbin[i].elt = elts[i]; @@ -426,15 +434,12 @@ qsort(sortbin, nelts, sizeof(*sortbin), reorder_sorter); - /* and now build a new array */ - /* XXX: uh I don't see why we can't reuse the old array, what - * was I thinking? -djg */ - sec = ap_make_array(p, nelts, sizeof(void *)); + /* and now copy back to the original array */ for (i = 0; i < nelts; ++i) { - *(void **)ap_push_array(sec) = sortbin[i].elt; + elts[i] = sortbin[i].elt; } - sconf->sec = sec; + ap_destroy_pool(tmp); } /***************************************************************** @@ -870,7 +875,7 @@ return FileTypeUNKNOWN; } - bResult = ReadFile(hFile, (void*) &buffer, sizeof(buffer), + bResult = ReadFile(hFile, (void*) &buffer, sizeof(buffer) - 1, &nBytesRead, NULL); if (!bResult || (nBytesRead == 0)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, @@ -897,7 +902,7 @@ } else { /* Check to see if it's a executable */ - IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)interpreter; + IMAGE_DOS_HEADER *hdr = (IMAGE_DOS_HEADER*)buffer; if (hdr->e_magic == IMAGE_DOS_SIGNATURE && hdr->e_cblp < 512) { fileType = FileTypeEXE; } @@ -1548,7 +1553,7 @@ conf->d_is_fnmatch = ap_is_fnmatch(conf->d) != 0; conf->r = r; - add_file_conf(c, new_file_conf); + ap_add_file_conf(c, new_file_conf); if (*arg != '\0') { return ap_pstrcat(cmd->pool, "Multiple ", thiscmd->name, @@ -2487,7 +2492,8 @@ conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - if (conf->server_signature == srv_sig_off) { + if ((conf->server_signature == srv_sig_off) + || (conf->server_signature == srv_sig_unset)) { return ""; } @@ -2761,7 +2767,7 @@ { "ServerName", set_server_string_slot, (void *)XtOffsetOf (server_rec, server_hostname), RSRC_CONF, TAKE1, "The hostname of the server" }, -{ "ServerSignature", set_signature_flag, NULL, ACCESS_CONF|RSRC_CONF, TAKE1, +{ "ServerSignature", set_signature_flag, NULL, OR_ALL, TAKE1, "En-/disable server signature (on|off|email)" }, { "ServerRoot", set_server_root, NULL, RSRC_CONF, TAKE1, "Common directory of server-related files (logs, confs, etc.)" }, @@ -2963,6 +2969,9 @@ #ifdef USE_MMAP_FILES caddr_t mm; #endif +#ifdef CHARSET_EBCDIC + int convert_flag; +#endif if (r->handler) { ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_WARNING, @@ -3026,6 +3035,7 @@ #ifdef USE_MMAP_FILES if ((r->finfo.st_size >= MMAP_THRESHOLD) + && (r->finfo.st_size < MMAP_LIMIT) && (!r->header_only || (d->content_md5 & 1))) { /* we need to protect ourselves in case we die while we've got the * file mmapped */ @@ -3043,23 +3053,28 @@ if (mm == (caddr_t)-1) { #endif - if (d->content_md5 & 1) { - ap_table_setn(r->headers_out, "Content-MD5", - ap_md5digest(r->pool, fd)); - } - - rangestatus = ap_set_byterange(r); #ifdef CHARSET_EBCDIC - /* To make serving of "raw ASCII text" files easy (they serve faster + /* To make serving of "raw ASCII text" files easy (they serve faster * since they don't have to be converted from EBCDIC), a new * "magic" type prefix was invented: text/x-ascii-{plain,html,...} * If we detect one of these content types here, we simply correct * the type to the real text/{plain,html,...} type. Otherwise, we * set a flag that translation is required later on. */ - ap_checkconv(r); -#endif /*CHARSET_EBCDIC*/ + convert_flag = ap_checkconv(r); + if (d->content_md5 & 1) { + ap_table_setn(r->headers_out, "Content-MD5", + ap_md5digest(r->pool, fd, convert_flag)); + } +#else + if (d->content_md5 & 1) { + ap_table_setn(r->headers_out, "Content-MD5", + ap_md5digest(r->pool, fd)); + } +#endif /* CHARSET_EBCDIC */ + rangestatus = ap_set_byterange(r); + ap_send_http_header(r); if (!r->header_only) { @@ -3095,7 +3110,7 @@ AP_MD5_CTX context; ap_MD5Init(&context); - ap_MD5Update(&context, (void *)mm, r->finfo.st_size); + ap_MD5Update(&context, (void *)mm, (unsigned int)r->finfo.st_size); ap_table_setn(r->headers_out, "Content-MD5", ap_md5contextTo64(r->pool, &context)); } 1.5 +42 -5 apache-apr/pthreads/src/main/http_log.c Index: http_log.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_log.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- http_log.c 1999/03/17 17:01:19 1.4 +++ http_log.c 1999/06/10 06:26:08 1.5 @@ -172,8 +172,10 @@ child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); return(child_pid); #elif defined(OS2) - /* For OS/2 we need to use a '/' */ - execl(SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + /* For OS/2 we need to use a '/' and spawn the child rather than exec as + * we haven't forked */ + child_pid = spawnl(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + return(child_pid); #else execl(SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL); #endif @@ -188,9 +190,17 @@ if (*s->error_fname == '|') { FILE *dummy; - +#ifdef TPF + TPF_FORK_CHILD cld; + cld.filename = s->error_fname+1; + cld.subprocess_env = NULL; + cld.prog_type = FORK_NAME; + if (!ap_spawn_child(p, NULL, &cld, + kill_after_timeout, &dummy, NULL, NULL)) { +#else if (!ap_spawn_child(p, error_log_child, (void *)(s->error_fname+1), kill_after_timeout, &dummy, NULL, NULL)) { +#endif /* TPF */ perror("ap_spawn_child"); fprintf(stderr, "Couldn't fork child for ErrorLog process\n"); exit(1); @@ -313,6 +323,18 @@ return; logf = s->error_log; } +#ifdef TPF + else if (tpf_child) { + /* + * If we are doing normal logging, don't log messages that are + * above the server log level unless it is a startup/shutdown notice + */ + if (((level & APLOG_LEVELMASK) != APLOG_NOTICE) && + ((level & APLOG_LEVELMASK) > s->loglevel)) + return; + logf = stderr; + } +#endif /* TPF */ else { /* * If we are doing syslog logging, don't log messages that are @@ -332,6 +354,7 @@ len += ap_snprintf(errstr + len, sizeof(errstr) - len, "[%s] ", priorities[level & APLOG_LEVELMASK].t_name); +#ifndef TPF if (file && (level & APLOG_LEVELMASK) == APLOG_DEBUG) { #ifdef _OSD_POSIX char tmp[256]; @@ -354,6 +377,7 @@ len += ap_snprintf(errstr + len, sizeof(errstr) - len, "%s(%d): ", file, line); } +#endif /* TPF */ if (r) { /* XXX: TODO: add a method of selecting whether logged client * addresses are in dotted quad or resolved form... dotted @@ -460,6 +484,8 @@ * something, even an empty string, into the "error-notes" cell * before calling this routine. */ + va_end(args); + va_start(args,fmt); if (((level & APLOG_LEVELMASK) <= APLOG_WARNING) && (ap_table_get(r->notes, "error-notes") == NULL)) { ap_table_setn(r->notes, "error-notes", @@ -700,8 +726,10 @@ child_pid = spawnl(_P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); return(child_pid); #elif defined(OS2) - /* For OS/2 we need to use a '/' */ - execl (SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + /* For OS/2 we need to use a '/' and spawn the child rather than exec as + * we haven't forked */ + child_pid = spawnl(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/c", (char *)cmd, NULL); + return(child_pid); #else execl (SHELL_PATH, SHELL_PATH, "-c", (char *)cmd, NULL); #endif @@ -715,9 +743,18 @@ { piped_log *pl; FILE *dummy; +#ifdef TPF + TPF_FORK_CHILD cld; + cld.filename = (char *)program; + cld.subprocess_env = NULL; + cld.prog_type = FORK_NAME; + if (!ap_spawn_child (p, NULL, &cld, + kill_after_timeout, &dummy, NULL, NULL)){ +#else if (!ap_spawn_child(p, piped_log_child, (void *)program, kill_after_timeout, &dummy, NULL, NULL)) { +#endif /* TPF */ perror("ap_spawn_child"); fprintf(stderr, "Couldn't fork child for piped log process\n"); exit (1); 1.92 +53 -26 apache-apr/pthreads/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_main.c,v retrieving revision 1.91 retrieving revision 1.92 diff -u -d -u -r1.91 -r1.92 --- http_main.c 1999/06/09 22:03:40 1.91 +++ http_main.c 1999/06/10 06:26:09 1.92 @@ -121,6 +121,12 @@ #define max(a,b) (a > b ? a : b) #endif +#ifdef WIN32 +#define PATHSEPARATOR '\\' +#else +#define PATHSEPARATOR '/' +#endif + DEF_Explain /* Defining GPROF when compiling uses the moncontrol() function to @@ -142,26 +148,26 @@ * for the most part the only code that acts on 'em. (Hmmm... mod_main.c?) */ -int ap_standalone; -uid_t ap_user_id; -char *ap_user_name; -gid_t ap_group_id; +int ap_standalone=0; +uid_t ap_user_id=0; +char *ap_user_name=NULL; +gid_t ap_group_id=0; #ifdef MULTIPLE_GROUPS gid_t group_id_list[NGROUPS_MAX]; #endif -int ap_threads_per_child; /* Worker threads per child */ -int ap_acceptors_per_child; /* Accept threads per child */ -int ap_max_requests_per_child; -char *ap_pid_fname; -char *ap_scoreboard_fname; +int ap_threads_per_child=0; /* Worker threads per child */ +int ap_acceptors_per_child=0; /* Accept threads per child */ +int ap_max_requests_per_child=0; +char *ap_pid_fname=NULL; +char *ap_scoreboard_fname=NULL; char *ap_lock_fname; -char *ap_server_argv0; +char *ap_server_argv0=NULL; struct in_addr ap_bind_address; /* ZZZZZ Abstract out the in_addr */ -int ap_daemons_to_start; -int ap_daemons_min_free; -int ap_daemons_max_free; -int ap_daemons_limit; -time_t ap_restart_time; +int ap_daemons_to_start=0; +int ap_daemons_min_free=0; +int ap_daemons_max_free=0; +int ap_daemons_limit=0; +time_t ap_restart_time=0; int ap_suexec_enabled = 0; int ap_listenbacklog; int ap_dump_settings = 0; @@ -195,8 +201,8 @@ */ listen_rec *ap_listeners; -API_VAR_EXPORT char ap_server_root[MAX_STRING_LEN]; -char ap_server_confname[MAX_STRING_LEN]; +API_VAR_EXPORT char ap_server_root[MAX_STRING_LEN]=""; +char ap_server_confname[MAX_STRING_LEN]=""; char ap_coredump_dir[MAX_STRING_LEN]; array_header *ap_server_pre_read_config; @@ -241,8 +247,9 @@ static other_child_rec *other_children; #endif -static pool *pperm; /* Pool for permananent stuff */ +static pool *pglobal; /* Global pool */ static pool *pconf; /* Pool for config stuff */ +static pool *plog; /* Pool for error-logging files */ static pool *ptemp; /* Pool for temporart config stuff */ static pool *pcommands; /* Pool for -C and -c switches */ @@ -342,7 +349,7 @@ static void clean_parent_exit(int code) { /* Clear the pool - including any registered cleanups */ - ap_destroy_pool(pconf); + ap_destroy_pool(pglobal); exit(code); } @@ -1299,7 +1306,7 @@ ap_note_cleanups_for_socket(p, s); /* arrange to close on exec or restart */ #endif -#ifndef WIN32 +#ifdef CHECK_FD_SETSIZE /* protect various fd_sets */ if (s >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, @@ -1558,14 +1565,15 @@ (void) set42sig(); #endif - pperm = ap_init_alloc(); - pconf = ap_make_sub_pool(pperm); + pglobal = ap_init_alloc(); + pconf = ap_make_sub_pool(pglobal); + plog = ap_make_sub_pool(pglobal); ptemp = ap_make_sub_pool(pconf); ap_util_init(); ap_util_uri_init(); - pcommands = ap_make_sub_pool(pperm); + pcommands = ap_make_sub_pool(pglobal); ap_server_pre_read_config = ap_make_array(pcommands, 1, sizeof(char *)); ap_server_post_read_config = ap_make_array(pcommands, 1, sizeof(char *)); } @@ -2019,6 +2027,8 @@ last_non_dead = -1; total_non_dead = 0; + ap_check_signals(); + ap_sync_scoreboard_image(); for (i = 0; i < ap_daemons_limit; ++i) { /* Initialization to satisfy the compiler. It doesn't know @@ -2215,7 +2225,8 @@ ptemp = ap_make_sub_pool(pconf); server_conf = ap_read_config(pconf, ptemp, ap_server_confname); listener_count = setup_listeners(pconf); - ap_open_logs(server_conf, pconf); + ap_clear_pool(plog); + ap_open_logs(server_conf, plog); ap_log_pid(pconf, ap_pid_fname); ap_set_version(); ap_init_modules(pconf, server_conf); @@ -2383,7 +2394,7 @@ common_init(); - if ((s = strrchr(argv[0], '/')) != NULL) { + if ((s = strrchr(argv[0], PATHSEPARATOR)) != NULL) { ap_server_argv0 = ++s; } else { @@ -2438,6 +2449,12 @@ case 'X': ++one_process; /* Weird debugging mode. */ break; +#ifdef TPF + case 'x': + os_tpf_child(&input_parms); + set_signals(); + break; +#endif #ifdef DEBUG_SIGSTOP case 'Z': raise_sigstop_flags = atoi(optarg); @@ -2485,8 +2502,18 @@ exit(1); } - ap_open_logs(server_conf, pconf); + ap_open_logs(server_conf, plog); ap_init_modules(pconf, server_conf); standalone_main(argc, argv); exit(0); } + +/* force Expat to be linked into the server executable */ +#if defined(USE_EXPAT) && !defined(SHARED_CORE_BOOTSTRAP) +#include "xmlparse.h" +const XML_LChar *suck_in_expat(void); +const XML_LChar *suck_in_expat(void) +{ + return XML_ErrorString(XML_ERROR_NONE); +} +#endif /* USE_EXPAT */ 1.18 +78 -7 apache-apr/pthreads/src/main/http_protocol.c Index: http_protocol.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_protocol.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -u -r1.17 -r1.18 --- http_protocol.c 1999/06/03 23:46:23 1.17 +++ http_protocol.c 1999/06/10 06:26:09 1.18 @@ -801,6 +801,10 @@ while ((len = getline(l, sizeof(l), conn->client, 0)) <= 0) { if ((len < 0) || ap_bgetflag(conn->client, B_EOF)) { ap_bsetflag(conn->client, B_SAFEREAD, 0); + /* this is a hack to make sure that request time is set, + * it's not perfect, but it's better than nothing + */ + r->request_time = time(0); return 0; } } @@ -1189,7 +1193,16 @@ * and must be listed in order. */ -static const char * const status_lines[RESPONSE_CODES] = { +#ifdef UTS21 +/* The second const triggers an assembler bug on UTS 2.1. + * Another workaround is to move some code out of this file into another, + * but this is easier. Dave Dykstra, 3/31/99 + */ +static const char * status_lines[RESPONSE_CODES] = +#else +static const char * const status_lines[RESPONSE_CODES] = +#endif +{ "100 Continue", "101 Switching Protocols", "102 Processing", @@ -1474,6 +1487,17 @@ r->headers_out = ap_overlay_tables(r->pool, r->err_headers_out, r->headers_out); + /* + * Remove the 'Vary' header field if the client can't handle it. + * Since this will have nasty effects on HTTP/1.1 caches, force + * the response into HTTP/1.0 mode. + */ + if (ap_table_get(r->subprocess_env, "force-no-vary") != NULL) { + ap_table_unset(r->headers_out, "Vary"); + r->proto_num = HTTP_VERSION(1,0); + ap_table_set(r->subprocess_env, "force-response-1.0", "1"); + } + ap_basic_http_header(r); #ifdef CHARSET_EBCDIC @@ -1964,7 +1988,7 @@ ap_bsetflag(fb, B_RD, 0); fd = ap_bfileno(fb, B_RD); ap_bnonblock(fd); -#ifndef WIN32 +#ifdef CHECK_FD_SETSIZE if (fd >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) " @@ -2175,6 +2199,28 @@ return n; } +API_EXPORT(int) ap_vrprintf(request_rec *r, const char *fmt, va_list ap) +{ + int n; + + if (r->connection->aborted) + return -1; + + n = ap_vbprintf(r->connection->client, fmt, ap); + + if (n < 0) { + if (!r->connection->aborted) { + ap_log_rerror(APLOG_MARK, APLOG_INFO, r, + "client stopped connection before vrprintf completed"); + ap_bsetflag(r->connection->client, B_EOUT, 1); + r->connection->aborted = 1; + } + return -1; + } + SET_BYTES_SENT(r); + return n; +} + API_EXPORT(int) ap_rprintf(request_rec *r, const char *fmt,...) { va_list vlist; @@ -2262,6 +2308,14 @@ char *custom_response; const char *location = ap_table_get(r->headers_out, "Location"); + /* + * It's possible that the Location field might be in r->err_headers_out + * instead of r->headers_out; use the latter if possible, else the + * former. + */ + if (location == NULL) { + location = ap_table_get(r->err_headers_out, "Location"); + } /* We need to special-case the handling of 204 and 304 responses, * since they have specific HTTP requirements and do not include a * message body. Note that being assbackwards here is not an option. @@ -2310,9 +2364,25 @@ r->err_headers_out = tmp; ap_clear_table(r->err_headers_out); - if (location && *location - && (ap_is_HTTP_REDIRECT(status) || status == HTTP_CREATED)) - ap_table_setn(r->headers_out, "Location", location); + if (ap_is_HTTP_REDIRECT(status) || (status == HTTP_CREATED)) { + if ((location != NULL) && *location) { + ap_table_setn(r->headers_out, "Location", location); + } + else { + /* + * We're supposed to tell the client to go somewhere, + * but the destination was omitted. Turn this into + * a 500 status with an explanatory note in the error log. + */ + ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r, + "resource created or redirection requested " + "(status=%03d) but no Location field set " + "(URI=%s)", + r->status, r->unparsed_uri); + r->status = status = HTTP_INTERNAL_SERVER_ERROR; + r->status_line = NULL; + } + } r->content_language = NULL; r->content_languages = NULL; @@ -2377,7 +2447,7 @@ h1 = &title[4]; ap_rvputs(r, - "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n" + DOCTYPE_HTML_2_0 "<HTML><HEAD>\n<TITLE>", title, "</TITLE>\n</HEAD><BODY>\n<H1>", h1, "</H1>\n", NULL); @@ -2570,7 +2640,8 @@ && (h1 = ap_table_get(r->notes, "verbose-error-to")) != NULL && (strcmp(h1, "*") == 0)) { ap_rvputs(r, error_notes, "<P>\n", NULL); - } else { + } + else { ap_rvputs(r, "The server encountered an internal error or\n" "misconfiguration and was unable to complete\n" "your request.<P>\n" 1.5 +16 -12 apache-apr/pthreads/src/main/http_request.c Index: http_request.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/http_request.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- http_request.c 1999/03/17 17:01:21 1.4 +++ http_request.c 1999/06/10 06:26:10 1.5 @@ -268,10 +268,15 @@ *cp = '\0'; return OK; } + /* must set this to zero, some stat()s may have corrupted it + * even if they returned an error. + */ + r->finfo.st_mode = 0; + /* ZZZ Let's throw some AP Errno checking in here and get rid of the #defines. */ #if defined(ENOENT) && defined(ENOTDIR) - else if (errno == ENOENT || errno == ENOTDIR) { + if (errno == ENOENT || errno == ENOTDIR) { last_cp = cp; while (--cp > path && *cp != '/') @@ -304,15 +309,13 @@ * you needed to do this. Please be sure to include the operating * system you are using. */ - else { - last_cp = cp; + last_cp = cp; - while (--cp > path && *cp != '/') - continue; + while (--cp > path && *cp != '/') + continue; - while (cp > path && cp[-1] == '/') - --cp; - } + while (cp > path && cp[-1] == '/') + --cp; #endif /* ENOENT && ENOTDIR */ } return OK; @@ -373,7 +376,7 @@ this_conf = NULL; if (entry_core->r) { - if (!regexec(entry_core->r, r->filename, 0, NULL, 0)) + if (!ap_regexec(entry_core->r, r->filename, 0, NULL, 0)) this_conf = entry_config; } else if (entry_core->d_is_fnmatch) { @@ -540,7 +543,7 @@ ap_get_module_config(entry_config, &core_module); if (entry_core->r) { - if (!regexec(entry_core->r, test_dirname, 0, NULL, REG_NOTEOL)) { + if (!ap_regexec(entry_core->r, test_dirname, 0, NULL, REG_NOTEOL)) { per_dir_defaults = ap_merge_per_dir_configs(r->pool, per_dir_defaults, entry_config); @@ -616,7 +619,7 @@ this_conf = NULL; if (entry_core->r) { - if (!regexec(entry_core->r, r->uri, 0, NULL, 0)) + if (!ap_regexec(entry_core->r, r->uri, 0, NULL, 0)) this_conf = entry_config; } else if (entry_core->d_is_fnmatch) { @@ -677,7 +680,7 @@ this_conf = NULL; if (entry_core->r) { - if (!regexec(entry_core->r, test_file, 0, NULL, 0)) + if (!ap_regexec(entry_core->r, test_file, 0, NULL, 0)) this_conf = entry_config; } else if (entry_core->d_is_fnmatch) { @@ -1323,6 +1326,7 @@ new->htaccess = r->htaccess; new->no_cache = r->no_cache; + new->expecting_100 = r->expecting_100; new->no_local_copy = r->no_local_copy; new->read_length = r->read_length; /* We can only read it once */ new->vlist_validator = r->vlist_validator; 1.5 +100 -23 apache-apr/pthreads/src/main/util.c Index: util.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/util.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- util.c 1999/04/17 03:06:38 1.4 +++ util.c 1999/06/10 06:26:10 1.5 @@ -121,6 +121,23 @@ return (time_string); } +/* + * Examine a field value (such as a media-/content-type) string and return + * it sans any parameters; e.g., strip off any ';charset=foo' and the like. + */ +API_EXPORT(char *) ap_field_noparam(pool *p, const char *intype) +{ + const char *semi; + + semi = strchr(intype, ';'); + if (semi != NULL) { + while ((semi > intype) && ap_isspace(semi[-1])) { + semi--; + } + } + return ap_pstrndup(p, intype, semi - intype); +} + API_EXPORT(char *) ap_ht_time(pool *p, time_t t, const char *fmt, int gmt) { /* ZZZ this function can be replaced by calls to time formatting routines @@ -327,9 +344,27 @@ return 0; } +/* + * Apache stub function for the regex libraries regexec() to make sure the + * whole regex(3) API is available through the Apache (exported) namespace. + * This is especially important for the DSO situations of modules. + * DO NOT MAKE A MACRO OUT OF THIS FUNCTION! + */ +API_EXPORT(int) ap_regexec(const regex_t *preg, const char *string, + size_t nmatch, regmatch_t pmatch[], int eflags) +{ + return regexec(preg, string, nmatch, pmatch, eflags); +} + +API_EXPORT(size_t) ap_regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) +{ + return regerror(errcode, preg, errbuf, errbuf_size); +} + + /* This function substitutes for $0-$9, filling in regular expression * submatches. Pass it the same nmatch and pmatch arguments that you - * passed regexec(). pmatch should not be greater than the maximum number + * passed ap_regexec(). pmatch should not be greater than the maximum number * of subexpressions - i.e. one more than the re_nsub member of regex_t. * * input should be the string with the $-expressions, source should be the @@ -1068,7 +1103,7 @@ } if ((*len = (ptr - token)) == 0) { - *field = ptr; + *field = (const char *)ptr; return NULL; } @@ -1077,7 +1112,7 @@ while (*ptr == ',' || ap_isspace(*ptr)) ++ptr; - *field = ptr; + *field = (const char *)ptr; return (const char *)token; } @@ -2015,7 +2050,7 @@ bufin = (const unsigned char *) bufcoded; - while (nprbytes > 0) { + while (nprbytes > 4) { *(bufout++) = (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); *(bufout++) = @@ -2026,13 +2061,19 @@ nprbytes -= 4; } - if (nprbytes & 03) { - if (pr2six[bufin[-2]] > 63) - nbytesdecoded -= 2; - else - nbytesdecoded -= 1; + /* Note: (nprbytes == 1) would be an error, so just ingore that case */ + if (nprbytes > 1) { + *(bufout++) = + (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4); } - bufplain[nbytesdecoded] = '\0'; + if (nprbytes > 2) { + *(bufout++) = + (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2); + } + if (nprbytes > 3) { + *(bufout++) = + (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]); + } #else /*CHARSET_EBCDIC*/ bufin = (const unsigned char *) bufcoded; while (pr2six[os_toascii[(unsigned char)*(bufin++)]] <= 63); @@ -2044,7 +2085,7 @@ bufin = (const unsigned char *) bufcoded; - while (nprbytes > 0) { + while (nprbytes > 4) { *(bufout++) = os_toebcdic[ (unsigned char) (pr2six[os_toascii[*bufin]] << 2 | pr2six[os_toascii[bufin[1]]] >> 4)]; *(bufout++) = os_toebcdic[ @@ -2055,14 +2096,24 @@ nprbytes -= 4; } - if (nprbytes & 03) { - if (pr2six[os_toascii[bufin[-2]]] > 63) - nbytesdecoded -= 2; - else - nbytesdecoded -= 1; + /* Note: (nprbytes == 1) would be an error, so just ingore that case */ + if (nprbytes > 1) { + *(bufout++) = os_toebcdic[ + (unsigned char) (pr2six[os_toascii[*bufin]] << 2 | pr2six[os_toascii[bufin[1]]] >> 4)]; } - bufplain[nbytesdecoded] = '\0'; + if (nprbytes > 2) { + *(bufout++) = os_toebcdic[ + (unsigned char) (pr2six[os_toascii[bufin[1]]] << 4 | pr2six[os_toascii[bufin[2]]] >> 2)]; + } + if (nprbytes > 3) { + *(bufout++) = os_toebcdic[ + (unsigned char) (pr2six[os_toascii[bufin[2]]] << 6 | pr2six[os_toascii[bufin[3]]])]; + } #endif /*CHARSET_EBCDIC*/ + + nbytesdecoded -= (4 - nprbytes) & 3; + bufplain[nbytesdecoded] = '\0'; + return bufplain; } @@ -2073,18 +2124,44 @@ { int i, len = strlen(string); char *p; - char *encoded = (char *) ap_pcalloc(a, (len+2) / 3 * 4); + char *encoded = (char *) ap_palloc(a, ((len+2) / 3 * 4) + 1); p = encoded; - for (i = 0; i < len; i += 3) { - *p++ = basis_64[string[i] >> 2]; +#ifndef CHARSET_EBCDIC + for (i = 0; i < len-2; i += 3) { + *p++ = basis_64[(string[i] >> 2) & 0x3F]; *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int) (string[i + 2] & 0xC0) >> 6)]; *p++ = basis_64[string[i + 2] & 0x3F]; } - *p-- = '\0'; - *p-- = '='; - *p-- = '='; + if (i < len) { + *p++ = basis_64[(string[i] >> 2) & 0x3F]; + *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; + if (i == (len-2)) + *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; + else + *p++ = '='; + *p++ = '='; + } +#else /*CHARSET_EBCDIC*/ + for (i = 0; i < len-2; i += 3) { + *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; + *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) | ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; + *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) | ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)]; + *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F]; + } + if (i < len) { + *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; + *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) | ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; + if (i == (len-2)) + *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)]; + else + *p++ = '='; + *p++ = '='; + } +#endif /*CHARSET_EBCDIC*/ + + *p = '\0'; return encoded; } 1.3 +29 -2 apache-apr/pthreads/src/main/util_md5.c Index: util_md5.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/util_md5.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- util_md5.c 1999/02/07 06:29:32 1.2 +++ util_md5.c 1999/06/10 06:26:11 1.3 @@ -100,7 +100,7 @@ */ ap_MD5Init(&my_md5); - ap_MD5Update(&my_md5, buf, length); + ap_MD5Update(&my_md5, buf, (unsigned int)length); ap_MD5Final(hash, &my_md5); for (i = 0, r = result; i < 16; i++) { @@ -114,7 +114,7 @@ API_EXPORT(char *) ap_md5(pool *p, const unsigned char *string) { - return ap_md5_binary(p, string, strlen(string)); + return ap_md5_binary(p, string, (int) strlen((char *)string)); } /* these portions extracted from mpack, John G. Myers - [EMAIL PROTECTED] */ @@ -187,6 +187,31 @@ return encodedDigest; } +#ifdef CHARSET_EBCDIC + +API_EXPORT(char *) ap_md5digest(pool *p, APRFile infile, int convert) +{ + AP_MD5_CTX context; + unsigned char buf[1000]; + long length = 0; + int nbytes; + + ap_MD5Init(&context); + /* ZZZ use AP func instead of fread. */ + while ((nbytes = read(infile, buf, sizeof(buf)))) { + length += nbytes; + if (!convert) { + ascii2ebcdic(buf, buf, nbytes); + } + ap_MD5Update(&context, buf, nbytes); + } + /* ZZZ use AP seek func instead of REWIND. */ + lseek(infile, 0L, SEEK_SET); + return ap_md5contextTo64(p, &context); +} + +#else + API_EXPORT(char *) ap_md5digest(pool *p, APRFile infile) { AP_MD5_CTX context; @@ -204,3 +229,5 @@ lseek(infile, 0L, SEEK_SET); return ap_md5contextTo64(p, &context); } + +#endif 1.7 +8 -30 apache-apr/pthreads/src/main/util_script.c Index: util_script.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/util_script.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -u -r1.6 -r1.7 --- util_script.c 1999/06/03 23:46:23 1.6 +++ util_script.c 1999/06/10 06:26:11 1.7 @@ -693,7 +693,7 @@ #endif -#ifndef WIN32 +#if !defined(WIN32) && !defined(OS2) /* the fd on r->server->error_log is closed, but we need somewhere to * put the error messages from the log_* functions. So, we use stderr, * since that is better than allowing errors to go unnoticed. Don't do @@ -768,52 +768,30 @@ } if ((!r->args) || (!r->args[0]) || strchr(r->args, '=')) { - int emxloop; - char *emxtemp; - - /* For OS/2 place the variables in the current - * environment then it will be inherited. This way - * the program will also get all of OS/2's other SETs. - */ - for (emxloop = 0; ((emxtemp = env[emxloop]) != NULL); emxloop++) { - putenv(emxtemp); - } - /* More additions by Alec Kloss for OS/2 */ if (is_script) { /* here's the stuff to run the interpreter */ - execl(interpreter + 2, interpreter + 2, r->filename, NULL); + pid = spawnle(P_NOWAIT, interpreter + 2, interpreter + 2, r->filename, NULL, env); } else if (strstr(strupr(r->filename), ".CMD") > 0) { /* Special case to allow use of REXX commands as scripts. */ os2pathname(r->filename); - execl(SHELL_PATH, SHELL_PATH, "/C", r->filename, NULL); + pid = spawnle(P_NOWAIT, SHELL_PATH, SHELL_PATH, "/C", r->filename, NULL, env); } else { - execl(r->filename, argv0, NULL); + pid = spawnle(P_NOWAIT, r->filename, argv0, NULL, env); } } else { - int emxloop; - char *emxtemp; - - /* For OS/2 place the variables in the current - * environment so that they will be inherited. This way - * the program will also get all of OS/2's other SETs. - */ - for (emxloop = 0; ((emxtemp = env[emxloop]) != NULL); emxloop++) { - putenv(emxtemp); - } - if (strstr(strupr(r->filename), ".CMD") > 0) { /* Special case to allow use of REXX commands as scripts. */ os2pathname(r->filename); - execv(SHELL_PATH, create_argv_cmd(r->pool, argv0, r->args, - r->filename)); + pid = spawnve(P_NOWAIT, SHELL_PATH, create_argv_cmd(r->pool, argv0, r->args, + r->filename), env); } else { - execv(r->filename, - create_argv(r->pool, NULL, NULL, NULL, argv0, r->args)); + pid = spawnve(P_NOWAIT, r->filename, + create_argv(r->pool, NULL, NULL, NULL, argv0, r->args), env); } } return (pid); 1.3 +4 -4 apache-apr/pthreads/src/main/util_uri.c Index: util_uri.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/main/util_uri.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- util_uri.c 1999/02/07 06:29:32 1.2 +++ util_uri.c 1999/06/10 06:26:11 1.3 @@ -306,11 +306,11 @@ memset (uptr, '\0', sizeof(*uptr)); uptr->is_initialized = 1; - ret = regexec(&re_uri, uri, re_uri.re_nsub + 1, match, 0); + ret = ap_regexec(&re_uri, uri, re_uri.re_nsub + 1, match, 0); if (ret != 0) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL, - "regexec() could not parse uri (\"%s\")", + "ap_regexec() could not parse uri (\"%s\")", uri); return HTTP_BAD_REQUEST; @@ -336,10 +336,10 @@ if (uptr->hostinfo) { /* Parse the hostinfo part to extract user, password, host, and port */ - ret = regexec(&re_hostpart, uptr->hostinfo, re_hostpart.re_nsub + 1, match, 0); + ret = ap_regexec(&re_hostpart, uptr->hostinfo, re_hostpart.re_nsub + 1, match, 0); if (ret != 0) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL, - "regexec() could not parse (\"%s\") as host part", + "ap_regexec() could not parse (\"%s\") as host part", uptr->hostinfo); return HTTP_BAD_REQUEST; 1.3 +1 -1 apache-apr/pthreads/src/modules/example/mod_example.c Index: mod_example.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/example/mod_example.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mod_example.c 1999/02/07 06:29:45 1.2 +++ mod_example.c 1999/06/10 06:26:20 1.3 @@ -523,7 +523,7 @@ * Now send our actual output. Since we tagged this as being * "text/html", we need to embed any HTML. */ - ap_rputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n", r); + ap_rputs(DOCTYPE_HTML_3_2, r); ap_rputs("<HTML>\n", r); ap_rputs(" <HEAD>\n", r); ap_rputs(" <TITLE>mod_example Module Content-Handler Output\n", r); 1.2 +2 -0 apache-apr/pthreads/src/modules/proxy/.cvsignore Index: .cvsignore =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- .cvsignore 1999/01/21 23:08:35 1.1 +++ .cvsignore 1999/06/10 06:26:21 1.2 @@ -8,3 +8,5 @@ Makefile *.lo *.so +*.dll +*.def 1.3 +6 -1 apache-apr/pthreads/src/modules/proxy/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/Makefile.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- Makefile.tmpl 1999/05/30 23:48:59 1.2 +++ Makefile.tmpl 1999/06/10 06:26:21 1.3 @@ -21,7 +21,12 @@ rm -f $@ $(LD_SHLIB) $(LDFLAGS_SHLIB) -o $@ $(OBJS_PIC) $(LIBS_SHLIB) -.SUFFIXES: .o .lo +libproxy.dll: $(OBJS_PIC) mod_proxy.def + $(LD_SHLIB) $(LDFLAGS_SHLIB) -o $* $(OBJS_PIC) $(LIBS_SHLIB) + emxbind -b -q -s -h0 -dmod_proxy.def $* && \ + rm $* + +.SUFFIXES: .o .lo .dll .c.o: $(CC) -c $(INCLUDES) $(CFLAGS) $< 1.10 +80 -43 apache-apr/pthreads/src/modules/proxy/proxy_cache.c Index: proxy_cache.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_cache.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -u -r1.9 -r1.10 --- proxy_cache.c 1999/06/09 22:03:42 1.9 +++ proxy_cache.c 1999/06/10 06:26:22 1.10 @@ -102,8 +102,7 @@ #define ROUNDUP2BLOCKS(_bytes) (((_bytes)+block_size-1) & ~(block_size-1)) static long block_size = 512; /* this must be a power of 2 */ static long61_t curbytes, cachesize; -static time_t every, garbage_now, garbage_expire; -static char *filename; +static time_t garbage_now, garbage_expire; static pthread_mutex_t garbage_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -116,6 +115,7 @@ static int sub_garbage_coll(request_rec *r, array_header *files, const char *cachedir, const char *cachesubdir); static void help_proxy_garbage_coll(request_rec *r); +static int should_proxy_garbage_coll(request_rec *r); #if !defined(WIN32) && !defined(MPE) && !defined(OS2) static void detached_proxy_garbage_coll(request_rec *r); #endif @@ -134,10 +134,11 @@ inside = 1; (void) pthread_mutex_unlock(&garbage_mutex); + if (should_proxy_garbage_coll(r)) #if !defined(WIN32) && !defined(MPE) && !defined(OS2) - detached_proxy_garbage_coll(r); + detached_proxy_garbage_coll(r); #else - help_proxy_garbage_coll(r); + help_proxy_garbage_coll(r); #endif (void) pthread_mutex_lock(&garbage_mutex); @@ -200,6 +201,10 @@ int status; pid_t pgrp; +#if 0 + ap_log_error(APLOG_MARK, APLOG_DEBUG, r->server, + "proxy: Guess what; we fork() again..."); +#endif switch (pid = fork()) { case -1: ap_log_error(APLOG_MARK, APLOG_ERR, r->server, @@ -259,27 +264,27 @@ } #endif /* ndef WIN32 */ -static void help_proxy_garbage_coll(request_rec *r) +#define DOT_TIME "/.time" /* marker */ + +static int should_proxy_garbage_coll(request_rec *r) { - const char *cachedir; void *sconf = r->server->module_config; proxy_server_conf *pconf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); const struct cache_conf *conf = &pconf->cache; - array_header *files; - struct stat buf; - struct gc_ent *fent; - int i, timefd; - static time_t lastcheck = BAD_DATE; /* static (per-process) data!!! */ - cachedir = conf->root; - /* configured size is given in kB. Make it bytes, convert to long61_t: */ - cachesize.lower = cachesize.upper = 0; - add_long61(&cachesize, conf->space << 10); - every = conf->gcinterval; + const char *cachedir = conf->root; + char *filename; + struct stat buf; + int timefd; + time_t every = conf->gcinterval; + static time_t lastcheck = BAD_DATE; /* static (per-process) data!!! */ if (cachedir == NULL || every == -1) - return; + return 0; + + filename = ap_palloc(r->pool, strlen(cachedir) + strlen( DOT_TIME ) +1); + garbage_now = time(NULL); /* Usually, the modification time of <cachedir>/.time can only increase. * Thus, even with several child processes having their own copy of @@ -287,37 +292,67 @@ * for GC yet. */ if (garbage_now != -1 && lastcheck != BAD_DATE && garbage_now < lastcheck + every) - return; + return 0; - filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2); strcpy(filename, cachedir); - strcat(filename, "/.time"); - if (stat(filename, &buf) == -1) { /* does not exist */ - if (errno != ENOENT) { - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, - "proxy: stat(%s)", filename); - return; - } - if ((timefd = creat(filename, 0666)) == -1) { - if (errno != EEXIST) - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, - "proxy: creat(%s)", filename); - else - lastcheck = garbage_now; /* someone else got in there */ - return; - } - close(timefd); + strcat(filename, DOT_TIME); + + /* At this point we have a bit of an engineering compromise. We could either + * create and/or mark the .time file (prior to the fork which might + * fail on a resource issue) or wait until we are safely forked. The + * advantage of doing it now in this process is that we get some + * usefull live out of the global last check variable. (XXX which + * should go scoreboard IMHO.) Note that the actual counting is + * at a later moment. + */ + if (stat(filename, &buf) == -1) { /* does not exist */ + if (errno != ENOENT) { + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "proxy: stat(%s)", filename); + return 0; + } + if ((timefd = creat(filename, 0666)) == -1) { + if (errno != EEXIST) + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "proxy: creat(%s)", filename); + else + lastcheck = garbage_now; /* someone else got in there */ + return 0; + } + close(timefd); } else { - lastcheck = buf.st_mtime; /* save the time */ - if (garbage_now < lastcheck + every) { - return; - } - if (utime(filename, NULL) == -1) - ap_log_error(APLOG_MARK, APLOG_ERR, r->server, - "proxy: utimes(%s)", filename); + lastcheck = buf.st_mtime; /* save the time */ + if (garbage_now < lastcheck + every) { + return 0; + } + if (utime(filename, NULL) == -1) + ap_log_error(APLOG_MARK, APLOG_ERR, r->server, + "proxy: utimes(%s)", filename); } + + return 1; +} + +static void help_proxy_garbage_coll(request_rec *r) +{ + const char *cachedir; + void *sconf = r->server->module_config; + proxy_server_conf *pconf = + (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); + const struct cache_conf *conf = &pconf->cache; + array_header *files; + struct gc_ent *fent; + char *filename; + int i; + + cachedir = conf->root; + filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2); + /* configured size is given in kB. Make it bytes, convert to long61_t: */ + cachesize.lower = cachesize.upper = 0; + add_long61(&cachesize, conf->space << 10); + files = ap_make_array(r->pool, 100, sizeof(struct gc_ent)); curbytes.upper = curbytes.lower = 0L; @@ -374,8 +409,10 @@ #endif struct gc_ent *fent; int nfiles = 0; + char *filename; ap_snprintf(cachedir, sizeof(cachedir), "%s%s", cachebasedir, cachesubdir); + filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2); Explain1("GC Examining directory %s", cachedir); dir = opendir(cachedir); if (dir == NULL) { @@ -764,7 +801,7 @@ int ap_proxy_cache_update(cache_req *c, table *resp_hdrs, const int is_HTTP1, int nocache) { -#ifdef ULTRIX_BRAIN_DEATH +#if defined(ULTRIX_BRAIN_DEATH) || defined(SINIX_D_RESOLVER_BUG) extern char *mktemp(char *template); #endif request_rec *r = c->req; 1.4 +1 -1 apache-apr/pthreads/src/modules/proxy/proxy_connect.c Index: proxy_connect.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_connect.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- proxy_connect.c 1999/03/17 17:01:42 1.3 +++ proxy_connect.c 1999/06/10 06:26:22 1.4 @@ -187,7 +187,7 @@ return HTTP_INTERNAL_SERVER_ERROR; } -#ifndef WIN32 +#ifdef CHECK_FD_SETSIZE if (sock >= FD_SETSIZE) { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL, "proxy_connect_handler: filedescriptor (%u) " 1.9 +30 -13 apache-apr/pthreads/src/modules/proxy/proxy_ftp.c Index: proxy_ftp.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_ftp.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -u -r1.8 -r1.9 --- proxy_ftp.c 1999/06/09 22:03:42 1.8 +++ proxy_ftp.c 1999/06/10 06:26:22 1.9 @@ -60,6 +60,7 @@ #include "mod_proxy.h" #include "http_main.h" #include "http_log.h" +#include "http_core.h" #define AUTODETECT_PWD @@ -290,7 +291,7 @@ path[n-1] = '\0'; /* print "ftp://host/" */ - n = ap_snprintf(buf, sizeof(buf), "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n" + n = ap_snprintf(buf, sizeof(buf), DOCTYPE_HTML_3_2 "<HTML><HEAD><TITLE>%s%s</TITLE>\n" "<BASE HREF=\"%s%s\"></HEAD>\n" "<BODY><H2>Directory of " @@ -322,8 +323,11 @@ while (!con->aborted) { n = ap_bgets(buf, sizeof buf, f); if (n == -1) { /* input error */ - if (c != NULL) + if (c != NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error reading from %s", c->url); c = ap_proxy_cache_error(c); + } break; } if (n == 0) @@ -382,8 +386,11 @@ o = 0; total_bytes_sent += n; - if (c != NULL && c->fp && ap_bwrite(c->fp, buf, n) != n) + if (c != NULL && c->fp && ap_bwrite(c->fp, buf, n) != n) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing to %s", c->tempfile); c = ap_proxy_cache_error(c); + } while (n && !r->connection->aborted) { w = ap_bwrite(con->client, &buf[o], n); @@ -1087,15 +1094,18 @@ resp_hdrs = ap_make_table(p, 2); c->hdrs = resp_hdrs; + ap_table_setn(resp_hdrs, "Date", ap_gm_timestr_822(r->pool, r->request_time)); + ap_table_setn(resp_hdrs, "Server", ap_get_server_version()); + if (parms[0] == 'd') - ap_table_set(resp_hdrs, "Content-Type", "text/html"); + ap_table_setn(resp_hdrs, "Content-Type", "text/html"); else { if (r->content_type != NULL) { - ap_table_set(resp_hdrs, "Content-Type", r->content_type); + ap_table_setn(resp_hdrs, "Content-Type", r->content_type); Explain1("FTP: Content-Type set to %s", r->content_type); } else { - ap_table_set(resp_hdrs, "Content-Type", "text/plain"); + ap_table_setn(resp_hdrs, "Content-Type", ap_default_type(r)); } if (parms[0] != 'a' && size != NULL) { /* We "trust" the ftp server to really serve (size) bytes... */ @@ -1103,6 +1113,10 @@ Explain1("FTP: Content-Length set to %s", size); } } + if (r->content_encoding != NULL && r->content_encoding[0] != '\0') { + Explain1("FTP: Content-Encoding set to %s", r->content_encoding); + ap_table_setn(resp_hdrs, "Content-Encoding", r->content_encoding); + } /* check if NoCache directive on this host */ for (i = 0; i < conf->nocaches->nelts; i++) { @@ -1142,17 +1156,16 @@ ap_bpushfd(data, dsock); } -#ifdef CHARSET_EBCDIC -/* bsetflag(data, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 0);*/ -#endif /*CHARSET_EBCDIC*/ - /* send response */ /* write status line */ if (!r->assbackwards) ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL); if (c != NULL && c->fp != NULL - && ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1) - c = ap_proxy_cache_error(c); + && ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing CRLF to %s", c->tempfile); + c = ap_proxy_cache_error(c); + } /* send headers */ tdo.req = r; @@ -1161,8 +1174,11 @@ if (!r->assbackwards) ap_rputs(CRLF, r); - if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) + if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing CRLF to %s", c->tempfile); c = ap_proxy_cache_error(c); + } ap_bsetopt(r->connection->client, BO_BYTECT, &zero); r->sent_bodyct = 1; @@ -1181,6 +1197,7 @@ /* XXX: we checked for 125||150||226||250 above. This is redundant. */ if (rc != 226 && rc != 250) + /* XXX: we no longer log an "error writing to c->tempfile" - should we? */ c = ap_proxy_cache_error(c); } else { 1.7 +20 -7 apache-apr/pthreads/src/modules/proxy/proxy_http.c Index: proxy_http.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_http.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -u -r1.6 -r1.7 --- proxy_http.c 1999/06/09 22:03:42 1.6 +++ proxy_http.c 1999/06/10 06:26:22 1.7 @@ -360,13 +360,17 @@ ap_bflush(f); len = ap_bgets(buffer, sizeof buffer - 1, f); - if (len == -1 || len == 0) { + if (len == -1) { ap_bclose(f); ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "ap_bgets() - proxy receive - Error reading from remote server %s", - proxyhost ? proxyhost : desthost); + "ap_bgets() - proxy receive - Error reading from remote server %s (length %d)", + proxyhost ? proxyhost : desthost, len); return ap_proxyerror(r, HTTP_BAD_GATEWAY, "Error reading from remote server"); + } else if (len == 0) { + ap_bclose(f); + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + "Document contains no data"); } /* Is it an HTTP/1 response? This is buggy if we ever see an HTTP/1.10 */ @@ -471,8 +475,11 @@ if (!r->assbackwards) ap_rvputs(r, "HTTP/1.0 ", r->status_line, CRLF, NULL); if (c != NULL && c->fp != NULL && - ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1) - c = ap_proxy_cache_error(c); + ap_bvputs(c->fp, "HTTP/1.0 ", r->status_line, CRLF, NULL) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing status line to %s", c->tempfile); + c = ap_proxy_cache_error(c); + } /* send headers */ tdo.req = r; @@ -481,16 +488,22 @@ if (!r->assbackwards) ap_rputs(CRLF, r); - if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) + if (c != NULL && c->fp != NULL && ap_bputs(CRLF, c->fp) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing CRLF to %s", c->tempfile); c = ap_proxy_cache_error(c); + } ap_bsetopt(r->connection->client, BO_BYTECT, &zero); r->sent_bodyct = 1; /* Is it an HTTP/0.9 respose? If so, send the extra data */ if (backasswards) { ap_bwrite(r->connection->client, buffer, len); - if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) != len) + if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) != len) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing extra data to %s", c->tempfile); c = ap_proxy_cache_error(c); + } } #ifdef CHARSET_EBCDIC 1.7 +18 -8 apache-apr/pthreads/src/modules/proxy/proxy_util.c Index: proxy_util.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/proxy/proxy_util.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -u -r1.6 -r1.7 --- proxy_util.c 1999/06/03 23:46:25 1.6 +++ proxy_util.c 1999/06/10 06:26:22 1.7 @@ -540,8 +540,11 @@ n = ap_bread(f, buf, IOBUFSIZE); if (n == -1) { /* input error */ - if (c != NULL) + if (c != NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error reading from %s", c->url); c = ap_proxy_cache_error(c); + } break; } if (n == 0) @@ -553,7 +556,9 @@ /*@@@ XXX FIXME: Assuming that writing the cache file won't time out?!!? */ if (c != NULL && c->fp != NULL) { if (ap_bwrite(c->fp, &buf[0], n) != n) { - c = ap_proxy_cache_error(c); + ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, + "proxy: error writing to %s", c->tempfile); + c = ap_proxy_cache_error(c); } else { c->written += n; } @@ -802,11 +807,13 @@ cache_req *ap_proxy_cache_error(cache_req *c) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req, - "proxy: error writing to cache file %s", c->tempfile); - ap_pclosef(c->req->pool, c->fp->fd); - c->fp = NULL; - unlink(c->tempfile); + if (c != NULL) { + if (c->fp != NULL) { + ap_pclosef(c->req->pool, c->fp->fd); + c->fp = NULL; + } + if (c->tempfile) unlink(c->tempfile); + } return NULL; } @@ -1240,8 +1247,11 @@ if (!parm->req->assbackwards) ap_rvputs(parm->req, key, ": ", value, CRLF, NULL); if (parm->cache != NULL && parm->cache->fp != NULL && - ap_bvputs(parm->cache->fp, key, ": ", value, CRLF, NULL) == -1) + ap_bvputs(parm->cache->fp, key, ": ", value, CRLF, NULL) == -1) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, parm->cache->req, + "proxy: error writing header to %s", parm->cache->tempfile); parm->cache = ap_proxy_cache_error(parm->cache); + } return 1; /* tell ap_table_do() to continue calling us for more headers */ } 1.2 +2 -0 apache-apr/pthreads/src/modules/standard/.cvsignore Index: .cvsignore =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- .cvsignore 1999/01/21 23:08:38 1.1 +++ .cvsignore 1999/06/10 06:26:24 1.2 @@ -1,3 +1,5 @@ Makefile *.lo *.so +*.dll +*.def 1.3 +1 -1 apache-apr/pthreads/src/modules/standard/mod_alias.c Index: mod_alias.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_alias.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mod_alias.c 1999/02/07 06:29:51 1.2 +++ mod_alias.c 1999/06/10 06:26:25 1.3 @@ -300,7 +300,7 @@ int l; if (p->regexp) { - if (!regexec(p->regexp, r->uri, p->regexp->re_nsub + 1, regm, 0)) { + if (!ap_regexec(p->regexp, r->uri, p->regexp->re_nsub + 1, regm, 0)) { if (p->real) { found = ap_pregsub(r->pool, p->real, r->uri, p->regexp->re_nsub + 1, regm); 1.5 +5 -0 apache-apr/pthreads/src/modules/standard/mod_auth_dbm.c Index: mod_auth_dbm.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_auth_dbm.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- mod_auth_dbm.c 1999/04/09 04:10:40 1.4 +++ mod_auth_dbm.c 1999/06/10 06:26:25 1.5 @@ -74,7 +74,12 @@ #include "http_core.h" #include "http_log.h" #include "http_protocol.h" +#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) \ + && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 +#include <db1/ndbm.h> +#else #include <ndbm.h> +#endif #include "ap_md5.h" /* 1.5 +339 -173 apache-apr/pthreads/src/modules/standard/mod_autoindex.c Index: mod_autoindex.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_autoindex.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- mod_autoindex.c 1999/02/07 06:29:51 1.4 +++ mod_autoindex.c 1999/06/10 06:26:25 1.5 @@ -72,6 +72,7 @@ #include "http_log.h" #include "http_main.h" #include "util_script.h" +#include "fnmatch.h" module MODULE_VAR_EXPORT autoindex_module; @@ -131,6 +132,13 @@ char *data; }; +typedef struct ai_desc_t { + char *pattern; + char *description; + int full_path; + int wildcards; +} ai_desc_t; + typedef struct autoindex_config_struct { char *default_icon; @@ -143,8 +151,12 @@ int icon_height; char *default_order; - array_header *icon_list, *alt_list, *desc_list, *ign_list; - array_header *hdr_list, *rdme_list; + array_header *icon_list; + array_header *alt_list; + array_header *desc_list; + array_header *ign_list; + array_header *hdr_list; + array_header *rdme_list; } autoindex_config_rec; @@ -180,7 +192,7 @@ */ static void emit_preamble(request_rec *r, char *title) { - ap_rvputs(r, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n", + ap_rvputs(r, DOCTYPE_HTML_3_2, "<HTML>\n <HEAD>\n <TITLE>Index of ", title, "</TITLE>\n </HEAD>\n <BODY>\n", NULL); } @@ -257,10 +269,48 @@ return NULL; } +/* + * Add description text for a filename pattern. If the pattern has + * wildcards already (or we need to add them), add leading and + * trailing wildcards to it to ensure substring processing. If the + * pattern contains a '/' anywhere, force wildcard matching mode, + * add a slash to the prefix so that "bar/bletch" won't be matched + * by "foobar/bletch", and make a note that there's a delimiter; + * the matching routine simplifies to just the actual filename + * whenever it can. This allows definitions in parent directories + * to be made for files in subordinate ones using relative paths. + */ + +/* + * Absent a strcasestr() function, we have to force wildcards on + * systems for which "AAA" and "aaa" mean the same file. + */ +#ifdef CASE_BLIND_FILESYSTEM +#define WILDCARDS_REQUIRED 1 +#else +#define WILDCARDS_REQUIRED 0 +#endif + static const char *add_desc(cmd_parms *cmd, void *d, char *desc, char *to) { - push_item(((autoindex_config_rec *) d)->desc_list, cmd->info, to, - cmd->path, desc); + autoindex_config_rec *dcfg = (autoindex_config_rec *) d; + ai_desc_t *desc_entry; + char *prefix = ""; + + desc_entry = (ai_desc_t *) ap_push_array(dcfg->desc_list); + desc_entry->full_path = (strchr(to, '/') == NULL) ? 0 : 1; + desc_entry->wildcards = (WILDCARDS_REQUIRED + || desc_entry->full_path + || ap_is_fnmatch(to)); + if (desc_entry->wildcards) { + prefix = desc_entry->full_path ? "*/" : "*"; + desc_entry->pattern = ap_pstrcat(dcfg->desc_list->pool, + prefix, to, "*", NULL); + } + else { + desc_entry->pattern = ap_pstrdup(dcfg->desc_list->pool, to); + } + desc_entry->description = ap_pstrdup(dcfg->desc_list->pool, desc); return NULL; } @@ -272,9 +322,6 @@ static const char *add_header(cmd_parms *cmd, void *d, char *name) { - if (strchr(name, '/')) { - return "HeaderName cannot contain a /"; - } push_item(((autoindex_config_rec *) d)->hdr_list, 0, NULL, cmd->path, name); return NULL; @@ -282,9 +329,6 @@ static const char *add_readme(cmd_parms *cmd, void *d, char *name) { - if (strchr(name, '/')) { - return "ReadmeName cannot contain a /"; - } push_item(((autoindex_config_rec *) d)->rdme_list, 0, NULL, cmd->path, name); return NULL; @@ -410,8 +454,8 @@ else { int width = atoi(&w[10]); - if (width < 1) { - return "NameWidth value must be greater than 1"; + if (width < 5) { + return "NameWidth value must be greater than 5"; } d_cfg->name_width = width; d_cfg->name_adjust = K_NOADJUST; @@ -530,7 +574,7 @@ new->name_adjust = K_UNSET; new->icon_list = ap_make_array(p, 4, sizeof(struct item)); new->alt_list = ap_make_array(p, 4, sizeof(struct item)); - new->desc_list = ap_make_array(p, 4, sizeof(struct item)); + new->desc_list = ap_make_array(p, 4, sizeof(ai_desc_t)); new->ign_list = ap_make_array(p, 4, sizeof(struct item)); new->hdr_list = ap_make_array(p, 4, sizeof(struct item)); new->rdme_list = ap_make_array(p, 4, sizeof(struct item)); @@ -688,7 +732,6 @@ #define find_icon(d,p,t) find_item(p,d->icon_list,t) #define find_alt(d,p,t) find_item(p,d->alt_list,t) -#define find_desc(d,p) find_item(p,d->desc_list,0) #define find_header(d,p) find_item(p,d->hdr_list,0) #define find_readme(d,p) find_item(p,d->rdme_list,0) @@ -707,6 +750,63 @@ return find_item(&r, d->icon_list, 1); } +/* + * Look through the list of pattern/description pairs and return the first one + * if any) that matches the filename in the request. If multiple patterns + * match, only the first one is used; since the order in the array is the + * same as the order in which directives were processed, earlier matching + * directives will dominate. + */ + +#ifdef CASE_BLIND_FILESYSTEM +#define MATCH_FLAGS FNM_CASE_BLIND +#else +#define MATCH_FLAGS 0 +#endif + +static char *find_desc(autoindex_config_rec *dcfg, request_rec *r) +{ + int i; + ai_desc_t *list = (ai_desc_t *) dcfg->desc_list->elts; + const char *filename_full = r->filename; + const char *filename_only; + const char *filename; + + /* + * If the filename includes a path, extract just the name itself + * for the simple matches. + */ + if ((filename_only = strrchr(filename_full, '/')) == NULL) { + filename_only = filename_full; + } + else { + filename_only++; + } + for (i = 0; i < dcfg->desc_list->nelts; ++i) { + ai_desc_t *tuple = &list[i]; + int found; + + /* + * Only use the full-path filename if the pattern contains '/'s. + */ + filename = (tuple->full_path) ? filename_full : filename_only; + /* + * Make the comparison using the cheapest method; only do + * wildcard checking if we must. + */ + if (tuple->wildcards) { + found = (ap_fnmatch(tuple->pattern, filename, MATCH_FLAGS) == 0); + } + else { + found = (strstr(filename, tuple->pattern) != NULL); + } + if (found) { + return tuple->description; + } + } + return NULL; +} + static int ignore_entry(autoindex_config_rec *d, char *path) { array_header *list = d->ign_list; @@ -758,99 +858,217 @@ */ /* - * Look for the specified file, and pump it into the response stream if we - * find it. + * Elements of the emitted document: + * Preamble + * Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req + * succeeds for the (content_type == text/html) header file. + * Header file + * Emitted if found (and able). + * H1 tag line + * Emitted if a header file is NOT emitted. + * Directory stuff + * Always emitted. + * HR + * Emitted if FANCY_INDEXING is set. + * Readme file + * Emitted if found (and able). + * ServerSig + * Emitted if ServerSignature is not Off AND a readme file + * is NOT emitted. + * Postamble + * Emitted unless SUPPRESS_PREAMBLE is set AND ap_run_sub_req + * succeeds for the (content_type == text/html) readme file. */ -static int insert_readme(char *name, char *readme_fname, char *title, - int hrule, int whichend, request_rec *r) + + +/* + * emit a plain text file + */ +static void do_emit_plain(request_rec *r, FILE *f) { - char *fn; - FILE *f; - struct stat finfo; - int plaintext = 0; - request_rec *rr; - autoindex_config_rec *cfg; - int autoindex_opts; + char buf[IOBUFSIZE + 1]; + int i, n, c, ch; - cfg = (autoindex_config_rec *) ap_get_module_config(r->per_dir_config, - &autoindex_module); - autoindex_opts = cfg->opts; - /* XXX: this is a load of crap, it needs to do a full sub_req_lookup_uri */ - fn = ap_make_full_path(r->pool, name, readme_fname); - fn = ap_pstrcat(r->pool, fn, ".html", NULL); - if (stat(fn, &finfo) == -1) { - /* A brief fake multiviews search for README.html */ - fn[strlen(fn) - 5] = '\0'; - if (stat(fn, &finfo) == -1) { - return 0; + ap_rputs("<PRE>\n", r); + while (!feof(f)) { + do { + n = fread(buf, sizeof(char), IOBUFSIZE, f); } - plaintext = 1; - if (hrule) { - ap_rputs("<HR>\n", r); + while (n == -1 && ferror(f) && errno == EINTR); + if (n == -1 || n == 0) { + break; } - } - else if (hrule) { - ap_rputs("<HR>\n", r); - } - /* XXX: when the above is rewritten properly, this necessary security - * check will be redundant. -djg */ - rr = ap_sub_req_lookup_file(fn, r); - if (rr->status != HTTP_OK) { - ap_destroy_sub_req(rr); - return 0; + buf[n] = '\0'; + c = 0; + while (c < n) { + for (i = c; i < n; i++) { + if (buf[i] == '<' || buf[i] == '>' || buf[i] == '&') { + break; + } + } + ch = buf[i]; + buf[i] = '\0'; + ap_rputs(&buf[c], r); + if (ch == '<') { + ap_rputs("<", r); + } + else if (ch == '>') { + ap_rputs(">", r); + } + else if (ch == '&') { + ap_rputs("&", r); + } + c = i + 1; + } } - ap_destroy_sub_req(rr); - if (!(f = ap_pfopen(r->pool, fn, "r"))) { - return 0; + ap_rputs("</PRE>\n", r); +} + +/* + * Handle the preamble through the H1 tag line, inclusive. Locate + * the file with a subrequests. Process text/html documents by actually + * running the subrequest; text/xxx documents get copied verbatim, + * and any other content type is ignored. This means that a non-text + * document (such as HEADER.gif) might get multiviewed as the result + * instead of a text document, meaning nothing will be displayed, but + * oh well. + */ +static void emit_head(request_rec *r, char *header_fname, int suppress_amble, + char *title) +{ + FILE *f; + request_rec *rr = NULL; + int emit_amble = 1; + int emit_H1 = 1; + + /* + * If there's a header file, send a subrequest to look for it. If it's + * found and a text file, handle it -- otherwise fall through and + * pretend there's nothing there. + */ + if ((header_fname != NULL) + && (rr = ap_sub_req_lookup_uri(header_fname, r)) + && (rr->status == HTTP_OK) + && (rr->filename != NULL) + && S_ISREG(rr->finfo.st_mode)) { + /* + * Check for the two specific cases we allow: text/html and + * text/anything-else. The former is allowed to be processed for + * SSIs. + */ + if (rr->content_type != NULL) { + if (!strcasecmp(ap_field_noparam(r->pool, rr->content_type), + "text/html")) { + /* Hope everything will work... */ + emit_amble = 0; + emit_H1 = 0; + + if (! suppress_amble) { + emit_preamble(r, title); + } + /* + * If there's a problem running the subrequest, display the + * preamble if we didn't do it before -- the header file + * didn't get displayed. + */ + if (ap_run_sub_req(rr) != OK) { + /* It didn't work */ + emit_amble = suppress_amble; + emit_H1 = 1; + } + } + else if (!strncasecmp("text/", rr->content_type, 5)) { + /* + * If we can open the file, prefix it with the preamble + * regardless; since we'll be sending a <PRE> block around + * the file's contents, any HTML header it had won't end up + * where it belongs. + */ + if ((f = ap_pfopen(r->pool, rr->filename, "r")) != 0) { + emit_preamble(r, title); + emit_amble = 0; + do_emit_plain(r, f); + ap_pfclose(r->pool, f); + emit_H1 = 0; + } + } + } } - if ((whichend == FRONT_MATTER) - && (!(autoindex_opts & SUPPRESS_PREAMBLE))) { + + if (emit_amble) { emit_preamble(r, title); } - if (!plaintext) { - ap_send_fd(fileno(f), r); + if (emit_H1) { + ap_rvputs(r, "<H1>Index of ", title, "</H1>\n", NULL); } - else { - char buf[IOBUFSIZE + 1]; - int i, n, c, ch; - ap_rputs("<PRE>\n", r); - while (!feof(f)) { - do { - n = fread(buf, sizeof(char), IOBUFSIZE, f); - } - while (n == -1 && ferror(f) && errno == EINTR); - if (n == -1 || n == 0) { - break; - } - buf[n] = '\0'; - c = 0; - while (c < n) { - for (i = c; i < n; i++) { - if (buf[i] == '<' || buf[i] == '>' || buf[i] == '&') { - break; - } - } - ch = buf[i]; - buf[i] = '\0'; - ap_rputs(&buf[c], r); - if (ch == '<') { - ap_rputs("<", r); - } - else if (ch == '>') { - ap_rputs(">", r); + if (rr != NULL) { + ap_destroy_sub_req(rr); + } +} + + +/* + * Handle the Readme file through the postamble, inclusive. Locate + * the file with a subrequests. Process text/html documents by actually + * running the subrequest; text/xxx documents get copied verbatim, + * and any other content type is ignored. This means that a non-text + * document (such as FOOTER.gif) might get multiviewed as the result + * instead of a text document, meaning nothing will be displayed, but + * oh well. + */ +static void emit_tail(request_rec *r, char *readme_fname, int suppress_amble) +{ + FILE *f; + request_rec *rr = NULL; + int suppress_post = 0; + int suppress_sig = 0; + + /* + * If there's a readme file, send a subrequest to look for it. If it's + * found and a text file, handle it -- otherwise fall through and + * pretend there's nothing there. + */ + if ((readme_fname != NULL) + && (rr = ap_sub_req_lookup_uri(readme_fname, r)) + && (rr->status == HTTP_OK) + && (rr->filename != NULL) + && S_ISREG(rr->finfo.st_mode)) { + /* + * Check for the two specific cases we allow: text/html and + * text/anything-else. The former is allowed to be processed for + * SSIs. + */ + if (rr->content_type != NULL) { + if (!strcasecmp(ap_field_noparam(r->pool, rr->content_type), + "text/html")) { + if (ap_run_sub_req(rr) == OK) { + /* worked... */ + suppress_sig = 1; + suppress_post = suppress_amble; } - else if (ch == '&') { - ap_rputs("&", r); + } + else if (!strncasecmp("text/", rr->content_type, 5)) { + /* + * If we can open the file, suppress the signature. + */ + if ((f = ap_pfopen(r->pool, rr->filename, "r")) != 0) { + do_emit_plain(r, f); + ap_pfclose(r->pool, f); + suppress_sig = 1; } - c = i + 1; } } } - ap_pfclose(r->pool, f); - if (plaintext) { - ap_rputs("</PRE>\n", r); + + if (!suppress_sig) { + ap_rputs(ap_psignature("", r), r); } - return 1; + if (!suppress_post) { + ap_rputs("</BODY></HTML>\n", r); + } + if (rr != NULL) { + ap_destroy_sub_req(rr); + } } @@ -863,8 +1081,9 @@ if (r->status != HTTP_OK) { return NULL; } - if (r->content_type - && (!strcmp(r->content_type, "text/html") + if ((r->content_type != NULL) + && (!strcasecmp(ap_field_noparam(r->pool, r->content_type), + "text/html") || !strcmp(r->content_type, INCLUDES_MAGIC_TYPE)) && !r->content_encoding) { if (!(thefile = ap_pfopen(r->pool, r->filename, "r"))) { @@ -933,7 +1152,6 @@ if (autoindex_opts & FANCY_INDEXING) { request_rec *rr = ap_sub_req_lookup_file(name, r); - fprintf(stderr, "sub_req:::: %s\n", name); if (rr->finfo.st_mode != 0) { p->lm = rr->finfo.st_mtime; @@ -1043,41 +1261,6 @@ } } -/* - * Fit a string into a specified buffer width, marking any - * truncation. The size argument is the actual buffer size, including - * the \0 termination byte. The buffer will be prefilled with blanks. - * If the pad argument is false, any extra spaces at the end of the - * buffer are omitted. (Used when constructing anchors.) - */ -static ap_inline char *widthify(const char *s, char *buff, int size, int pad) -{ - int s_len; - - memset(buff, ' ', size); - buff[size - 1] = '\0'; - s_len = strlen(s); - if (s_len > (size - 1)) { - ap_cpystrn(buff, s, size); - if (size > 1) { - buff[size - 2] = '>'; - } - if (size > 2) { - buff[size - 3] = '.'; - } - if (size > 3) { - buff[size - 4] = '.'; - } - } - else { - ap_cpystrn(buff, s, s_len + 1); - if (pad) { - buff[s_len] = ' '; - } - } - return buff; -} - static void output_directories(struct ent **ar, int n, autoindex_config_rec *d, request_rec *r, int autoindex_opts, char keyid, char direction) @@ -1089,6 +1272,7 @@ pool *scratch = ap_make_sub_pool(r->pool); int name_width; char *name_scratch; + char *pad_scratch; if (name[0] == '\0') { name = "/"; @@ -1103,10 +1287,10 @@ } } } - ++name_width; name_scratch = ap_palloc(r->pool, name_width + 1); - memset(name_scratch, ' ', name_width); - name_scratch[name_width] = '\0'; + pad_scratch = ap_palloc(r->pool, name_width + 1); + memset(pad_scratch, ' ', name_width); + pad_scratch[name_width] = '\0'; if (autoindex_opts & FANCY_INDEXING) { ap_rputs("<PRE>", r); @@ -1123,15 +1307,9 @@ ); } ap_rputs("> ", r); - } - emit_link(r, widthify("Name", name_scratch, - (name_width > 5) ? 5 : name_width, K_NOPAD), - K_NAME, keyid, direction, static_columns); - if (name_width > 5) { - memset(name_scratch, ' ', name_width); - name_scratch[name_width] = '\0'; - ap_rputs(&name_scratch[5], r); } + emit_link(r, "Name", K_NAME, keyid, direction, static_columns); + ap_rputs(pad_scratch + 4, r); /* * Emit the guaranteed-at-least-one-space-between-columns byte. */ @@ -1157,7 +1335,6 @@ for (x = 0; x < n; x++) { char *anchor, *t, *t2; - char *pad; int nwidth; ap_clear_pool(scratch); @@ -1168,15 +1345,12 @@ if (t[0] == '\0') { t = "/"; } - /* 1234567890123456 */ t2 = "Parent Directory"; - pad = name_scratch + 16; anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0)); } else { t = ar[x]->name; - pad = name_scratch + strlen(t); - t2 = ap_escape_html(scratch, t); + t2 = t; anchor = ap_escape_html(scratch, ap_os_escape_path(scratch, t, 0)); } @@ -1201,18 +1375,19 @@ ap_rputs("</A>", r); } - ap_rvputs(r, " <A HREF=\"", anchor, "\">", - widthify(t2, name_scratch, name_width, K_NOPAD), - "</A>", NULL); - /* - * We know that widthify() prefilled the buffer with spaces - * before doing its thing, so use them. - */ nwidth = strlen(t2); - if (nwidth < (name_width - 1)) { - name_scratch[nwidth] = ' '; - ap_rputs(&name_scratch[nwidth], r); + if (nwidth > name_width) { + memcpy(name_scratch, t2, name_width - 3); + name_scratch[name_width - 3] = '.'; + name_scratch[name_width - 2] = '.'; + name_scratch[name_width - 1] = '>'; + name_scratch[name_width] = 0; + t2 = name_scratch; + nwidth = name_width; } + ap_rvputs(r, " <A HREF=\"", anchor, "\">", + ap_escape_html(scratch, t2), "</A>", pad_scratch + nwidth, + NULL); /* * The blank before the storm.. er, before the next field. */ @@ -1242,7 +1417,7 @@ } else { ap_rvputs(r, "<LI><A HREF=\"", anchor, "\"> ", t2, - "</A>", pad, NULL); + "</A>", NULL); } ap_rputc('\n', r); } @@ -1327,7 +1502,6 @@ int num_ent = 0, x; struct ent *head, *p; struct ent **ar = NULL; - char *tmp; const char *qstring; int autoindex_opts = autoindex_conf->opts; char keyid; @@ -1356,12 +1530,8 @@ *title_endp-- = '\0'; } - if ((!(tmp = find_header(autoindex_conf, r))) - || (!(insert_readme(name, tmp, title_name, NO_HRULE, FRONT_MATTER, r))) - ) { - emit_preamble(r, title_name); - ap_rvputs(r, "<H1>Index of ", title_name, "</H1>\n", NULL); - } + emit_head(r, find_header(autoindex_conf, r), + autoindex_opts & SUPPRESS_PREAMBLE, title_name); /* * Figure out what sort of indexing (if any) we're supposed to use. @@ -1426,15 +1596,11 @@ direction); ap_pclosedir(r->pool, d); - if ((tmp = find_readme(autoindex_conf, r))) { - if (!insert_readme(name, tmp, "", - ((autoindex_opts & FANCY_INDEXING) ? HRULE - : NO_HRULE), - END_MATTER, r)) { - ap_rputs(ap_psignature("<HR>\n", r), r); - } + if (autoindex_opts & FANCY_INDEXING) { + ap_rputs("<HR>\n", r); } - ap_rputs("</BODY></HTML>\n", r); + emit_tail(r, find_readme(autoindex_conf, r), + autoindex_opts & SUPPRESS_PREAMBLE); return 0; } 1.6 +13 -1 apache-apr/pthreads/src/modules/standard/mod_cgi.c Index: mod_cgi.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_cgi.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -u -r1.5 -r1.6 --- mod_cgi.c 1999/06/03 23:46:27 1.5 +++ mod_cgi.c 1999/06/10 06:26:25 1.6 @@ -275,6 +275,9 @@ struct cgi_child_stuff { +#ifdef TPF + TPF_FORK_CHILD t; +#endif request_rec *r; int nph; int debug; @@ -325,10 +328,13 @@ * NB only ISINDEX scripts get decoded arguments. */ +#ifdef TPF + return (0); +#else ap_cleanup_for_exec(); child_pid = ap_call_exec(r, pinfo, argv0, env, 0); -#ifdef WIN32 +#if defined(WIN32) || defined(OS2) return (child_pid); #else @@ -346,6 +352,7 @@ /* NOT REACHED */ return (0); #endif +#endif /* TPF */ } static int cgi_handler(request_rec *r) @@ -419,6 +426,11 @@ cld.r = r; cld.nph = nph; cld.debug = conf->logname ? 1 : 0; +#ifdef TPF + cld.t.filename = r->filename; + cld.t.subprocess_env = r->subprocess_env; + cld.t.prog_type = FORK_FILE; +#endif /* TPF */ #ifdef CHARSET_EBCDIC /* XXX:@@@ Is the generated/included output ALWAYS in text/ebcdic format? */ 1.3 +1 -1 apache-apr/pthreads/src/modules/standard/mod_dir.c Index: mod_dir.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_dir.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mod_dir.c 1999/02/07 06:29:52 1.2 +++ mod_dir.c 1999/06/10 06:26:25 1.3 @@ -161,7 +161,7 @@ char *name_ptr = *names_ptr; request_rec *rr = ap_sub_req_lookup_uri(name_ptr, r); - if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) { + if (rr->status == HTTP_OK && S_ISREG(rr->finfo.st_mode)) { char *new_uri = ap_escape_uri(r->pool, rr->uri); if (rr->args != NULL) 1.3 +23 -27 apache-apr/pthreads/src/modules/standard/mod_env.c Index: mod_env.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_env.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mod_env.c 1999/02/07 06:29:52 1.2 +++ mod_env.c 1999/06/10 06:26:25 1.3 @@ -105,26 +105,26 @@ table *vars; char *unsetenv; int vars_present; -} env_server_config_rec; +} env_dir_config_rec; module MODULE_VAR_EXPORT env_module; -static void *create_env_server_config(pool *p, server_rec *dummy) +static void *create_env_dir_config(pool *p, char *dummy) { - env_server_config_rec *new = - (env_server_config_rec *) ap_palloc(p, sizeof(env_server_config_rec)); + env_dir_config_rec *new = + (env_dir_config_rec *) ap_palloc(p, sizeof(env_dir_config_rec)); new->vars = ap_make_table(p, 50); new->unsetenv = ""; new->vars_present = 0; return (void *) new; } -static void *merge_env_server_configs(pool *p, void *basev, void *addv) +static void *merge_env_dir_configs(pool *p, void *basev, void *addv) { - env_server_config_rec *base = (env_server_config_rec *) basev; - env_server_config_rec *add = (env_server_config_rec *) addv; - env_server_config_rec *new = - (env_server_config_rec *) ap_palloc(p, sizeof(env_server_config_rec)); + env_dir_config_rec *base = (env_dir_config_rec *) basev; + env_dir_config_rec *add = (env_dir_config_rec *) addv; + env_dir_config_rec *new = + (env_dir_config_rec *) ap_palloc(p, sizeof(env_dir_config_rec)); table *new_table; table_entry *elts; @@ -166,11 +166,10 @@ return new; } -static const char *add_env_module_vars_passed(cmd_parms *cmd, char *struct_ptr, +static const char *add_env_module_vars_passed(cmd_parms *cmd, + env_dir_config_rec *sconf, const char *arg) { - env_server_config_rec *sconf = - ap_get_module_config(cmd->server->module_config, &env_module); table *vars = sconf->vars; char *env_var; char *name_ptr; @@ -186,11 +185,10 @@ return NULL; } -static const char *add_env_module_vars_set(cmd_parms *cmd, char *struct_ptr, +static const char *add_env_module_vars_set(cmd_parms *cmd, + env_dir_config_rec *sconf, const char *arg) { - env_server_config_rec *sconf = - ap_get_module_config(cmd->server->module_config, &env_module); table *vars = sconf->vars; char *name, *value; @@ -212,11 +210,10 @@ return NULL; } -static const char *add_env_module_vars_unset(cmd_parms *cmd, char *struct_ptr, +static const char *add_env_module_vars_unset(cmd_parms *cmd, + env_dir_config_rec *sconf, char *arg) { - env_server_config_rec *sconf = - ap_get_module_config(cmd->server->module_config, &env_module); sconf->unsetenv = sconf->unsetenv ? ap_pstrcat(cmd->pool, sconf->unsetenv, " ", arg, NULL) : arg; @@ -226,19 +223,18 @@ static const command_rec env_module_cmds[] = { {"PassEnv", add_env_module_vars_passed, NULL, - RSRC_CONF, RAW_ARGS, "a list of environment variables to pass to CGI."}, + OR_FILEINFO, RAW_ARGS, "a list of environment variables to pass to CGI."}, {"SetEnv", add_env_module_vars_set, NULL, - RSRC_CONF, RAW_ARGS, "an environment variable name and a value to pass to CGI."}, + OR_FILEINFO, RAW_ARGS, "an environment variable name and a value to pass to CGI."}, {"UnsetEnv", add_env_module_vars_unset, NULL, - RSRC_CONF, RAW_ARGS, "a list of variables to remove from the CGI environment."}, + OR_FILEINFO, RAW_ARGS, "a list of variables to remove from the CGI environment."}, {NULL}, }; static int fixup_env_module(request_rec *r) { table *e = r->subprocess_env; - server_rec *s = r->server; - env_server_config_rec *sconf = ap_get_module_config(s->module_config, + env_dir_config_rec *sconf = ap_get_module_config(r->per_dir_config, &env_module); table *vars = sconf->vars; @@ -254,10 +250,10 @@ { STANDARD_MODULE_STUFF, NULL, /* initializer */ - NULL, /* dir config creater */ - NULL, /* dir merger --- default is to override */ - create_env_server_config, /* server config */ - merge_env_server_configs, /* merge server configs */ + create_env_dir_config, /* dir config creater */ + merge_env_dir_configs, /* dir merger --- default is to override */ + NULL, /* server config */ + NULL, /* merge server configs */ env_module_cmds, /* command table */ NULL, /* handlers */ NULL, /* filename translation */ 1.3 +1 -1 apache-apr/pthreads/src/modules/standard/mod_imap.c Index: mod_imap.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_imap.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mod_imap.c 1999/02/07 06:29:53 1.2 +++ mod_imap.c 1999/06/10 06:26:26 1.3 @@ -508,7 +508,7 @@ ap_send_http_header(r); - ap_rvputs(r, "<html><head>\n<title>Menu for ", r->uri, + ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ", r->uri, "</title>\n</head><body>\n", NULL); if (!strcasecmp(menu, "formatted")) { 1.5 +42 -25 apache-apr/pthreads/src/modules/standard/mod_include.c Index: mod_include.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_include.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- mod_include.c 1999/03/17 17:01:51 1.4 +++ mod_include.c 1999/06/10 06:26:26 1.5 @@ -767,6 +767,9 @@ } typedef struct { +#ifdef TPF + TPF_FORK_CHILD t; +#endif request_rec *r; char *s; } include_cmd_arg; @@ -820,11 +823,14 @@ #ifdef DEBUG_INCLUDE_CMD fprintf(dbg, "Attempting to exec '%s'\n", s); #endif +#ifdef TPF + return (0); +#else ap_cleanup_for_exec(); /* set shellcmd flag to pass arg to SHELL_PATH */ child_pid = ap_call_exec(r, pinfo, s, ap_create_environment(r->pool, env), 1); -#ifdef WIN32 +#if defined(WIN32) || defined(OS2) return (child_pid); #else /* Oh, drat. We're still here. The log file descriptors are closed, @@ -842,6 +848,7 @@ /* NOT REACHED */ return (child_pid); #endif /* WIN32 */ +#endif /* TPF */ } static int include_cmd(char *s, request_rec *r) @@ -851,6 +858,11 @@ arg.r = r; arg.s = s; +#ifdef TPF + arg.t.filename = r->filename; + arg.t.subprocess_env = r->subprocess_env; + arg.t.prog_type = FORK_FILE; +#endif if (!ap_bspawn_child(r->pool, include_cmd_child, &arg, kill_after_timeout, NULL, &script_in, NULL)) { @@ -1037,35 +1049,41 @@ static int find_file(request_rec *r, const char *directive, const char *tag, char *tag_val, struct stat *finfo, const char *error) { - char *to_send; - request_rec *rr; + char *to_send = tag_val; + request_rec *rr = NULL; int ret=0; + char *error_fmt = NULL; if (!strcmp(tag, "file")) { - ap_getparents(tag_val); /* get rid of any nasties */ - - rr = ap_sub_req_lookup_file(tag_val, r); + /* be safe; only files in this directory or below allowed */ + if (!is_only_below(tag_val)) { + error_fmt = "unable to access file \"%s\" " + "in parsed file %s"; + } + else { + ap_getparents(tag_val); /* get rid of any nasties */ + rr = ap_sub_req_lookup_file(tag_val, r); - if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) { - to_send = rr->filename; - if ((ret = stat(to_send, finfo)) == -1) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "unable to get information about \"%s\" " - "in parsed file %s", - to_send, r->filename); - ap_rputs(error, r); + if (rr->status == HTTP_OK && rr->finfo.st_mode != 0) { + to_send = rr->filename; + if (stat(to_send, finfo)) { + error_fmt = "unable to get information about \"%s\" " + "in parsed file %s"; + } + } + else { + error_fmt = "unable to lookup information about \"%s\" " + "in parsed file %s"; } } - else { + + if (error_fmt) { ret = -1; - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - "unable to lookup information about \"%s\" " - "in parsed file %s", - tag_val, r->filename); + ap_log_rerror(APLOG_MARK, APLOG_ERR, r, error_fmt, to_send, r->filename); ap_rputs(error, r); } - - ap_destroy_sub_req(rr); + + if (rr) ap_destroy_sub_req(rr); return ret; } @@ -1120,9 +1138,8 @@ } else { int l, x; -#if defined(BSD) && BSD > 199305 - /* ap_snprintf can't handle %qd */ - sprintf(tag, "%qd", finfo.st_size); +#if defined(AP_OFF_T_IS_QUAD) + ap_snprintf(tag, sizeof(tag), "%qd", finfo.st_size); #else ap_snprintf(tag, sizeof(tag), "%ld", finfo.st_size); #endif @@ -1173,7 +1190,7 @@ "unable to compile pattern \"%s\"", rexp); return -1; } - regex_error = regexec(compiled, string, 0, (regmatch_t *) NULL, 0); + regex_error = ap_regexec(compiled, string, 0, (regmatch_t *) NULL, 0); ap_pregfree(r->pool, compiled); return (!regex_error); } 1.7 +2 -1 apache-apr/pthreads/src/modules/standard/mod_info.c Index: mod_info.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_info.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -u -r1.6 -r1.7 --- mod_info.c 1999/04/22 05:13:41 1.6 +++ mod_info.c 1999/06/10 06:26:26 1.7 @@ -377,7 +377,8 @@ return 0; } - ap_rputs("<html><head><title>Server Information</title></head>\n", r); + ap_rputs(DOCTYPE_HTML_3_2 + "<html><head><title>Server Information</title></head>\n", r); ap_rputs("<body><h1 align=center>Apache Server Information</h1>\n", r); if (!r->args || strcasecmp(r->args, "list")) { cfname = ap_server_root_relative(r->pool, ap_server_confname); 1.5 +4 -6 apache-apr/pthreads/src/modules/standard/mod_log_config.c Index: mod_log_config.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_log_config.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- mod_log_config.c 1999/03/24 18:39:53 1.4 +++ mod_log_config.c 1999/06/10 06:26:26 1.5 @@ -384,16 +384,14 @@ } else { /* CLF format */ char sign = (timz < 0 ? '-' : '+'); - size_t l; if (timz < 0) { timz = -timz; } - - strftime(tstr, MAX_STRING_LEN, "[%d/%b/%Y:%H:%M:%S ", t); - l = strlen(tstr); - ap_snprintf(tstr + l, sizeof(tstr) - l, - "%c%.2d%.2d]", sign, timz / 60, timz % 60); + ap_snprintf(tstr, sizeof(tstr), "[%02d/%s/%d:%02d:%02d:%02d %c%.2d%.2d]", + t->tm_mday, ap_month_snames[t->tm_mon], t->tm_year+1900, + t->tm_hour, t->tm_min, t->tm_sec, + sign, timz / 60, timz % 60); } return ap_pstrdup(r->pool, tstr); 1.3 +2 -7 apache-apr/pthreads/src/modules/standard/mod_mime.c Index: mod_mime.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_mime.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mod_mime.c 1999/02/07 06:29:54 1.2 +++ mod_mime.c 1999/06/10 06:26:26 1.3 @@ -233,13 +233,8 @@ * get private versions through AddType... */ -/* MIME_HASHSIZE used to be 27 (26 chars and one "non-alpha" slot), but - * with character sets like EBCDIC, this is insufficient because the - * range 'a'...'z' is not contigous. Defining it as ('z'-'a'+2) is - * equivalent to 27 in ASCII, and makes it work in EBCDIC. - */ -#define MIME_HASHSIZE ('z'-'a'+2) -#define hash(i) (ap_isalpha(i) ? (ap_tolower(i)) - 'a' : (MIME_HASHSIZE-1)) +#define MIME_HASHSIZE (32) +#define hash(i) (ap_tolower(i) % MIME_HASHSIZE) static table *hash_buckets[MIME_HASHSIZE]; 1.8 +25 -20 apache-apr/pthreads/src/modules/standard/mod_mime_magic.c Index: mod_mime_magic.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_mime_magic.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -u -r1.7 -r1.8 --- mod_mime_magic.c 1999/06/03 23:46:27 1.7 +++ mod_mime_magic.c 1999/06/10 06:26:27 1.8 @@ -242,7 +242,7 @@ static int ascmagic(request_rec *, unsigned char *, int); static int is_tar(unsigned char *, int); static int softmagic(request_rec *, unsigned char *, int); -static void tryit(request_rec *, unsigned char *, int); +static void tryit(request_rec *, unsigned char *, int, int); static int zmagic(request_rec *, unsigned char *, int); static int getvalue(server_rec *, struct magic *, char **); @@ -256,7 +256,7 @@ static int mcheck(request_rec *, union VALUETYPE *, struct magic *); static void mprint(request_rec *, union VALUETYPE *, struct magic *); -static int uncompress(request_rec *, int, const unsigned char *, +static int uncompress(request_rec *, int, unsigned char **, int); static long from_oct(int, char *); static int fsmagic(request_rec *r, const char *fn); @@ -887,7 +887,7 @@ magic_rsl_puts(r, MIME_TEXT_UNKNOWN); else { buf[nbytes++] = '\0'; /* null-terminate it */ - tryit(r, buf, nbytes); + tryit(r, buf, nbytes, 1); } (void) ap_pclosef(r->pool, fd); @@ -897,13 +897,15 @@ } -static void tryit(request_rec *r, unsigned char *buf, int nb) +static void tryit(request_rec *r, unsigned char *buf, int nb, int checkzmagic) { /* * Try compression stuff */ - if (zmagic(r, buf, nb) == 1) - return; + if (checkzmagic == 1) { + if (zmagic(r, buf, nb) == 1) + return; + } /* * try tests in /etc/magic (or surrogate magic file) @@ -2082,9 +2084,13 @@ char *encoding; /* MUST be lowercase */ } compr[] = { + /* we use gzip here rather than uncompress because we have to pass + * it a full filename -- and uncompress only considers filenames + * ending with .Z + */ { "\037\235", 2, { - "uncompress", "-c", NULL + "gzip", "-dcq", NULL }, 0, "x-compress" }, { @@ -2121,8 +2127,8 @@ if (i == ncompr) return 0; - if ((newsize = uncompress(r, i, buf, &newbuf, nbytes)) > 0) { - tryit(r, newbuf, newsize); + if ((newsize = uncompress(r, i, &newbuf, nbytes)) > 0) { + tryit(r, newbuf, newsize, 0); /* set encoding type in the request record */ r->content_encoding = compr[i].encoding; @@ -2140,13 +2146,19 @@ { struct uncompress_parms *parm = data; int child_pid; + char *new_argv[4]; + new_argv[0] = compr[parm->method].argv[0]; + new_argv[1] = compr[parm->method].argv[1]; + new_argv[2] = parm->r->filename; + new_argv[3] = NULL; + if (compr[parm->method].silent) { close(STDERR_FILENO); } child_pid = ap_spawnvp(compr[parm->method].argv[0], - compr[parm->method].argv); + new_argv); if (child_pid == -1) ap_log_rerror(APLOG_MARK, APLOG_ERR, parm->r, MODNAME ": could not execute `%s'.", @@ -2155,11 +2167,11 @@ } -static int uncompress(request_rec *r, int method, const unsigned char *old, +static int uncompress(request_rec *r, int method, unsigned char **newch, int n) { struct uncompress_parms parm; - BUFF *bin, *bout; + BUFF *bout; pool *sub_pool; parm.r = r; @@ -2172,19 +2184,12 @@ sub_pool = ap_make_sub_pool(r->pool); if (!ap_bspawn_child(sub_pool, uncompress_child, &parm, kill_always, - &bin, &bout, NULL)) { + NULL, &bout, NULL)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, r, MODNAME ": couldn't spawn uncompress process: %s", r->uri); return -1; } - if (ap_bwrite(bin, old, n) != n) { - ap_destroy_pool(sub_pool); - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, - MODNAME ": write failed."); - return -1; - } - ap_bclose(bin); *newch = (unsigned char *) ap_palloc(r->pool, n); if ((n = ap_bread(bout, *newch, n)) <= 0) { ap_destroy_pool(sub_pool); 1.4 +0 -29 apache-apr/pthreads/src/modules/standard/mod_negotiation.c Index: mod_negotiation.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_negotiation.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- mod_negotiation.c 1999/03/17 17:01:52 1.3 +++ mod_negotiation.c 1999/06/10 06:26:27 1.4 @@ -140,7 +140,6 @@ typedef struct accept_rec { char *name; /* MUST be lowercase */ float quality; - float max_bytes; float level; char *charset; /* for content-type only */ } accept_rec; @@ -315,7 +314,6 @@ const char *accept_line) { result->quality = 1.0f; - result->max_bytes = 0.0f; result->level = 0.0f; result->charset = ""; @@ -392,10 +390,6 @@ && (parm[1] == '\0' || (parm[1] == 's' && parm[2] == '\0'))) { result->quality = atof(cp); } - else if (parm[0] == 'm' && parm[1] == 'x' && - parm[2] == 'b' && parm[3] == '\0') { - result->max_bytes = atof(cp); - } else if (parm[0] == 'l' && !strcmp(&parm[1], "evel")) { result->level = atof(cp); } @@ -613,7 +607,6 @@ new_accept->name = "*/*"; new_accept->quality = 1.0f; new_accept->level = 0.0f; - new_accept->max_bytes = 0.0f; } new_accept = (accept_rec *) ap_push_array(neg->accepts); @@ -626,7 +619,6 @@ new_accept->quality = prefer_scripts ? 2.0f : 0.001f; } new_accept->level = 0.0f; - new_accept->max_bytes = 0.0f; } /***************************************************************** @@ -837,9 +829,6 @@ has_content = 1; } else if (!strncmp(buffer, "description:", 12)) { - /* XXX: The possibility to set a description is - * currently not documented. - */ char *desc = ap_pstrdup(neg->pool, body); char *cp; @@ -1523,13 +1512,6 @@ } } - /* Check maxbytes -- not in HTTP/1.1 or TCN */ - - if (type->max_bytes > 0 - && (find_content_length(neg, variant) > type->max_bytes)) { - continue; - } - /* If we are allowed to mess with the q-values * and have no explicit q= parameters in the accept header, * make wildcards very low, so we have a low chance @@ -1914,9 +1896,6 @@ /* If the best variant's charset is ISO-8859-1 and this variant has * the same charset quality, then we prefer this variant */ - /* XXX: TODO: this specific tie-breaker is not described in the - * documentation - */ if (variant->charset_quality > best->charset_quality || ((variant->content_charset != NULL && @@ -2212,14 +2191,6 @@ ap_array_pstrcat(r->pool, arr, '\0')); } - /* Theoretically the negotiation result _always_ has a dependence on - * the contents of the Accept header because we do 'mxb=' - * processing in set_accept_quality(). However, variations in mxb - * only affect the relative quality of several acceptable variants, - * so there is no reason to worry about an unacceptable variant - * being mistakenly prioritized. We therefore ignore mxb in deciding - * whether or not to include Accept in the Vary field value. - */ if (neg->is_transparent || vary_by_type || vary_by_language || vary_by_language || vary_by_charset || vary_by_encoding) { 1.5 +7 -4 apache-apr/pthreads/src/modules/standard/mod_rewrite.c Index: mod_rewrite.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_rewrite.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- mod_rewrite.c 1999/03/24 18:39:54 1.4 +++ mod_rewrite.c 1999/06/10 06:26:27 1.5 @@ -529,7 +529,10 @@ static const char *cmd_rewritelock(cmd_parms *cmd, void *dconf, char *a1) { rewrite_server_conf *sconf; + const char *error; + if ((error = ap_check_cmd_context(cmd, GLOBAL_ONLY)) != NULL) + return error; sconf = (rewrite_server_conf *) ap_get_module_config(cmd->server->module_config, &rewrite_module); @@ -1796,7 +1799,7 @@ rewritelog(r, 3, "[per-dir %s] applying pattern '%s' to uri '%s'", perdir, p->pattern, uri); } - rc = (regexec(regexp, uri, regexp->re_nsub+1, regmatch, 0) == 0); + rc = (ap_regexec(regexp, uri, regexp->re_nsub+1, regmatch, 0) == 0); if (! (( rc && !(p->flags & RULEFLAG_NOTMATCH)) || (!rc && (p->flags & RULEFLAG_NOTMATCH)) ) ) { return 0; @@ -2172,7 +2175,7 @@ } } } - else if (strcmp(p->pattern, "-s ") == 0) { + else if (strcmp(p->pattern, "-s") == 0) { if (stat(input, &sb) == 0) { if (S_ISREG(sb.st_mode) && sb.st_size > 0) { rc = 1; @@ -2265,8 +2268,8 @@ } else { /* it is really a regexp pattern, so apply it */ - rc = (regexec(p->regexp, input, - p->regexp->re_nsub+1, regmatch,0) == 0); + rc = (ap_regexec(p->regexp, input, + p->regexp->re_nsub+1, regmatch,0) == 0); /* if it isn't a negated pattern and really matched we update the passed-through regex subst info structure */ 1.4 +9 -1 apache-apr/pthreads/src/modules/standard/mod_rewrite.h Index: mod_rewrite.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_rewrite.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- mod_rewrite.h 1999/03/17 17:01:54 1.3 +++ mod_rewrite.h 1999/06/10 06:26:28 1.4 @@ -105,6 +105,7 @@ #include <sys/stat.h> /* Include from the Apache server ... */ +#define CORE_PRIVATE #include "httpd.h" #include "http_config.h" #include "http_conf_globals.h" @@ -126,8 +127,15 @@ * so we also need to know the file extension */ #ifndef NO_DBM_REWRITEMAP +#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) \ + && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1 +#include <db1/ndbm.h> +#else #include <ndbm.h> -#if defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM)) +#endif +#if defined(DBM_SUFFIX) +#define NDBM_FILE_SUFFIX DBM_SUFFIX +#elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM)) #define NDBM_FILE_SUFFIX ".db" #else #define NDBM_FILE_SUFFIX ".pag" 1.4 +12 -2 apache-apr/pthreads/src/modules/standard/mod_setenvif.c Index: mod_setenvif.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_setenvif.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- mod_setenvif.c 1999/03/24 18:39:55 1.3 +++ mod_setenvif.c 1999/06/10 06:26:28 1.4 @@ -125,7 +125,8 @@ SPECIAL_REMOTE_HOST, SPECIAL_REMOTE_USER, SPECIAL_REQUEST_URI, - SPECIAL_REQUEST_METHOD + SPECIAL_REQUEST_METHOD, + SPECIAL_REQUEST_PROTOCOL }; typedef struct { char *name; /* header name */ @@ -241,6 +242,9 @@ else if (!strcasecmp(fname, "request_method")) { new->special_type = SPECIAL_REQUEST_METHOD; } + else if (!strcasecmp(fname, "request_protocol")) { + new->special_type = SPECIAL_REQUEST_PROTOCOL; + } else { new->special_type = SPECIAL_NOT; } @@ -355,8 +359,14 @@ case SPECIAL_REQUEST_METHOD: val = r->method; break; + case SPECIAL_REQUEST_PROTOCOL: + val = r->protocol; + break; case SPECIAL_NOT: val = ap_table_get(r->headers_in, b->name); + if (val == NULL) { + val = ap_table_get(r->subprocess_env, b->name); + } break; } } @@ -371,7 +381,7 @@ val = ""; } - if (!regexec(b->preg, val, 0, NULL, 0)) { + if (!ap_regexec(b->preg, val, 0, NULL, 0)) { array_header *arr = ap_table_elts(b->features); elts = (table_entry *) arr->elts; 1.5 +3 -3 apache-apr/pthreads/src/modules/standard/mod_so.c Index: mod_so.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_so.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- mod_so.c 1999/03/17 17:01:55 1.4 +++ mod_so.c 1999/06/10 06:26:28 1.5 @@ -251,7 +251,7 @@ "' in file ", szModuleFile, ": ", ap_os_dso_error(), NULL); } modi->modp = modp; - modp->dynamic_load_handle = modhandle; + modp->dynamic_load_handle = (void *)modhandle; /* * Make sure the found module structure is really a module structure @@ -291,7 +291,7 @@ static const char *load_file(cmd_parms *cmd, void *dummy, char *filename) { - void *handle; + ap_os_dso_handle_t handle; char *file; file = ap_server_root_relative(cmd->pool, filename); @@ -307,7 +307,7 @@ ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, NULL, "loaded file %s", filename); - ap_register_cleanup(cmd->pool, handle, unload_file, ap_null_cleanup); + ap_register_cleanup(cmd->pool, (void *)handle, unload_file, ap_null_cleanup); return NULL; } 1.12 +3 -1 apache-apr/pthreads/src/modules/standard/mod_status.c Index: mod_status.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_status.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -u -r1.11 -r1.12 --- mod_status.c 1999/04/26 22:46:53 1.11 +++ mod_status.c 1999/06/10 06:26:28 1.12 @@ -344,7 +344,9 @@ /* ap_hard_timeout("send status info", r); */ if (!short_report) { - ap_rputs("<HTML><HEAD>\n<TITLE>Apache Status</TITLE>\n</HEAD><BODY>\n", r); + ap_rputs(DOCTYPE_HTML_3_2 + "<HTML><HEAD>\n<TITLE>Apache Status</TITLE>\n</HEAD><BODY>\n", + r); ap_rputs("<H1>Apache Server Status for ", r); ap_rvputs(r, ap_get_server_name(r), "</H1>\n\n", NULL); ap_rvputs(r, "Server Version: ", 1.3 +53 -22 apache-apr/pthreads/src/modules/standard/mod_usertrack.c Index: mod_usertrack.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/standard/mod_usertrack.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mod_usertrack.c 1999/02/07 06:29:56 1.2 +++ mod_usertrack.c 1999/06/10 06:26:28 1.3 @@ -111,7 +111,12 @@ typedef struct { int always; time_t expires; -} cookie_log_state; +} cookie_log_state; + +typedef struct { + int enabled; + char *cookie_name; +} cookie_dir_rec; /* Define this to allow post-2000 cookies. Cookies use two-digit dates, * so it might be dicey. (Netscape does it correctly, but others may not) @@ -121,12 +126,12 @@ /* Make Cookie: Now we have to generate something that is going to be * pretty unique. We can base it on the pid, time, hostip */ -#define COOKIE_NAME "Apache=" +#define COOKIE_NAME "Apache" static void make_cookie(request_rec *r) { cookie_log_state *cls = ap_get_module_config(r->server->module_config, - &usertrack_module); + &usertrack_module); #if defined(NO_GETTIMEOFDAY) && !defined(NO_TIMES) clock_t mpe_times; struct tms mpe_tms; @@ -138,8 +143,11 @@ char cookiebuf[1024]; char *new_cookie; const char *rname = ap_get_remote_host(r->connection, r->per_dir_config, - REMOTE_NAME); + REMOTE_NAME); + cookie_dir_rec *dcfg; + dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module); + #if defined(NO_GETTIMEOFDAY) && !defined(NO_TIMES) /* We lack gettimeofday(), so we must use time() to obtain the epoch seconds, and then times() to obtain CPU clock ticks (milliseconds). @@ -147,7 +155,8 @@ mpe_times = times(&mpe_tms); - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, (int) getpid(), + ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, + (int) getpid(), (long) r->request_time, (long) mpe_tms.tms_utime); #elif defined(WIN32) /* @@ -156,13 +165,15 @@ * was started. It should be relatively unique. */ - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, (int) getpid(), + ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%ld", rname, + (int) getpid(), (long) r->request_time, (long) GetTickCount()); #else gettimeofday(&tv, &tz); - ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%d", rname, (int) getpid(), + ap_snprintf(cookiebuf, sizeof(cookiebuf), "%s.%d%ld%d", rname, + (int) getpid(), (long) tv.tv_sec, (int) tv.tv_usec / 1000); #endif @@ -184,14 +195,16 @@ /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */ new_cookie = ap_psprintf(r->pool, - "%s%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", - COOKIE_NAME, cookiebuf, ap_day_snames[tms->tm_wday], + "%s=%s; path=/; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", + dcfg->cookie_name, cookiebuf, ap_day_snames[tms->tm_wday], tms->tm_mday, ap_month_snames[tms->tm_mon], tms->tm_year % 100, tms->tm_hour, tms->tm_min, tms->tm_sec); } - else - new_cookie = ap_psprintf(r->pool, "%s%s; path=/", COOKIE_NAME, cookiebuf); + else { + new_cookie = ap_psprintf(r->pool, "%s=%s; path=/", + dcfg->cookie_name, cookiebuf); + } ap_table_setn(r->headers_out, "Set-Cookie", new_cookie); ap_table_setn(r->notes, "cookie", ap_pstrdup(r->pool, cookiebuf)); /* log first time */ @@ -200,19 +213,20 @@ static int spot_cookie(request_rec *r) { - int *enable = (int *) ap_get_module_config(r->per_dir_config, - &usertrack_module); + cookie_dir_rec *dcfg = ap_get_module_config(r->per_dir_config, + &usertrack_module); const char *cookie; char *value; - if (!*enable) + if (!dcfg->enabled) { return DECLINED; + } if ((cookie = ap_table_get(r->headers_in, "Cookie"))) - if ((value = strstr(cookie, COOKIE_NAME))) { + if ((value = strstr(cookie, dcfg->cookie_name))) { char *cookiebuf, *cookieend; - value += strlen(COOKIE_NAME); + value += strlen(dcfg->cookie_name) + 1; /* Skip over the '=' */ cookiebuf = ap_pstrdup(r->pool, value); cookieend = strchr(cookiebuf, ';'); if (cookieend) @@ -221,7 +235,7 @@ /* Set the cookie in a note, for logging */ ap_table_setn(r->notes, "cookie", cookiebuf); - return DECLINED; /* Theres already a cookie, no new one */ + return DECLINED; /* There's already a cookie, no new one */ } make_cookie(r); return OK; /* We set our cookie */ @@ -239,12 +253,19 @@ static void *make_cookie_dir(pool *p, char *d) { - return (void *) ap_pcalloc(p, sizeof(int)); + cookie_dir_rec *dcfg; + + dcfg = (cookie_dir_rec *) ap_pcalloc(p, sizeof(cookie_dir_rec)); + dcfg->cookie_name = COOKIE_NAME; + dcfg->enabled = 0; + return dcfg; } -static const char *set_cookie_enable(cmd_parms *cmd, int *c, int arg) +static const char *set_cookie_enable(cmd_parms *cmd, void *mconfig, int arg) { - *c = arg; + cookie_dir_rec *dcfg = mconfig; + + dcfg->enabled = arg; return NULL; } @@ -315,11 +336,21 @@ return NULL; } +static const char *set_cookie_name(cmd_parms *cmd, void *mconfig, char *name) +{ + cookie_dir_rec *dcfg = (cookie_dir_rec *) mconfig; + + dcfg->cookie_name = ap_pstrdup(cmd->pool, name); + return NULL; +} + static const command_rec cookie_log_cmds[] = { {"CookieExpires", set_cookie_exp, NULL, RSRC_CONF, TAKE1, - "an expiry date code"}, + "an expiry date code"}, {"CookieTracking", set_cookie_enable, NULL, OR_FILEINFO, FLAG, - "whether or not to enable cookies"}, + "whether or not to enable cookies"}, + {"CookieName", set_cookie_name, NULL, OR_FILEINFO, TAKE1, + "name of the tracking cookie"}, {NULL} }; 1.3 +2 -1 apache-apr/pthreads/src/modules/test/mod_test_util_uri.c Index: mod_test_util_uri.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/modules/test/mod_test_util_uri.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- mod_test_util_uri.c 1999/02/07 06:30:09 1.2 +++ mod_test_util_uri.c 1999/06/10 06:26:35 1.3 @@ -275,7 +275,8 @@ } ap_hard_timeout("test_util_uri", r); - ap_rputs(" + ap_rputs( +DOCTYPE_HTML_2_0 " <html><body> <p>Key: <dl> 1.4 +1 -0 apache-apr/pthreads/src/os/bs2000/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/bs2000/os.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- os.h 1999/03/17 17:02:04 1.3 +++ os.h 1999/06/10 06:26:36 1.4 @@ -32,6 +32,7 @@ /* Other ap_os_ routines not used by this platform */ #define ap_os_is_filename_valid(f) (1) +#define ap_os_kill(pid, sig) kill(pid, sig) /* Sorry if this is ugly, but the include order doesn't allow me * to use request_rec here... */ 1.2 +16 -8 apache-apr/pthreads/src/os/os2/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/os2/Makefile.tmpl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- Makefile.tmpl 1999/01/21 23:08:40 1.1 +++ Makefile.tmpl 1999/06/10 06:26:37 1.2 @@ -8,13 +8,7 @@ LIB= libos.a -all: $(LIB) copy - -copy: - for i in $(COPY); do \ - rm -f $(INCDIR)/$$i ;\ - cp `pwd`/$$i $(INCDIR)/$$i ;\ - done +all: $(LIB) $(LIB): $(OBJS) rm -f $@ @@ -33,6 +27,12 @@ $(OBJS): Makefile +$(INCDIR)/os.h: os.h + cp $< $@ + +$(INCDIR)/os-inline.c: os-inline.c + cp $< $@ + # We really don't expect end users to use this rule. It works only with # gcc, and rebuilds Makefile.tmpl. You have to re-run Configure after # using it. @@ -46,4 +46,12 @@ && rm Makefile.new # DO NOT REMOVE -os.o: os.c os-inline.c +os-inline.o: os-inline.c $(INCDIR)/ap_config.h \ + $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ + $(INCDIR)/os.h $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h +os.o: os.c os.h os-inline.c +util_os2.o: util_os2.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ + $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ + $(INCDIR)/os.h $(INCDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ + $(INCDIR)/hsregex.h $(INCDIR)/alloc.h $(INCDIR)/buff.h \ + $(INCDIR)/ap.h $(INCDIR)/util_uri.h $(INCDIR)/http_log.h 1.2 +52 -0 apache-apr/pthreads/src/os/os2/os.c Index: os.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/os2/os.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- os.c 1999/01/21 23:08:40 1.1 +++ os.c 1999/06/10 06:26:37 1.2 @@ -4,3 +4,55 @@ */ #include "os.h" +#define INCL_DOS +#include <os2.h> +#include <stdio.h> + +static int rc=0; + +void ap_os_dso_init(void) +{ +} + + + +ap_os_dso_handle_t ap_os_dso_load(const char *module_name) +{ + char errorstr[200]; + HMODULE handle; + + rc = DosLoadModule(errorstr, sizeof(errorstr), module_name, &handle); + + if (rc == 0) + return handle; + + return 0; +} + + + +void ap_os_dso_unload(ap_os_dso_handle_t handle) +{ + DosFreeModule(handle); +} + + + +void *ap_os_dso_sym(ap_os_dso_handle_t handle, const char *funcname) +{ + PFN func; + + rc = DosQueryProcAddr( handle, 0, funcname, &func ); + + if (rc == 0) + return func; + + return NULL; +} + + + +const char *ap_os_dso_error(void) +{ + return ap_os_error_message(rc); +} 1.4 +14 -0 apache-apr/pthreads/src/os/os2/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/os2/os.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- os.h 1999/03/17 17:02:05 1.3 +++ os.h 1999/06/10 06:26:37 1.4 @@ -32,7 +32,21 @@ /* FIXME: the following should be implemented on this platform */ #define ap_os_is_filename_valid(f) (1) +/* Use a specialized kill() function */ +int ap_os_kill(int pid, int sig); + +/* Maps an OS error code to an error message */ +char *ap_os_error_message(int err); + /* OS/2 doesn't have symlinks so S_ISLNK is always false */ #define S_ISLNK(m) 0 + +/* Dynamic loading functions */ +#define ap_os_dso_handle_t unsigned long +void ap_os_dso_init(void); +ap_os_dso_handle_t ap_os_dso_load(const char *); +void ap_os_dso_unload(ap_os_dso_handle_t); +void * ap_os_dso_sym(ap_os_dso_handle_t, const char *); +const char *ap_os_dso_error(void); #endif /* ! APACHE_OS_H */ 1.3 +56 -0 apache-apr/pthreads/src/os/os2/util_os2.c Index: util_os2.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/os2/util_os2.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- util_os2.c 1999/03/17 17:02:05 1.2 +++ util_os2.c 1999/06/10 06:26:37 1.3 @@ -1,5 +1,6 @@ #define INCL_DOSFILEMGR #define INCL_DOSERRORS +#define INCL_DOSEXCEPTIONS #include <os2.h> #include "httpd.h" #include "http_log.h" @@ -38,4 +39,59 @@ *pos = '/'; return ap_pstrdup(pPool, buf2); +} + + + +int ap_os_kill(pid_t pid, int sig) +{ +/* SIGTERM's don't work too well in OS/2 (only affects other EMX programs). + CGIs may not be, esp. REXX scripts, so use a native call instead */ + + int rc; + + if ( sig == SIGTERM ) { + rc = DosSendSignalException( pid, XCPT_SIGNAL_BREAK ); + + if ( rc ) { + errno = ESRCH; + rc = -1; + } + } else { + rc = kill(pid, sig); + } + + return rc; +} + + + +char *ap_os_error_message(int err) +{ + static char result[200]; + char message[HUGE_STRING_LEN]; + ULONG len; + char *pos; + int c; + + if (DosGetMessage(NULL, 0, message, HUGE_STRING_LEN, err, "OSO001.MSG", &len) == 0) { + len--; + message[len] = 0; + pos = result; + + if (len >= sizeof(result)) + len = sizeof(result-1); + + for (c=0; c<len; c++) { + while (isspace(message[c]) && isspace(message[c+1])) /* skip multiple whitespace */ + c++; + *(pos++) = isspace(message[c]) ? ' ' : message[c]; + } + + *pos = 0; + } else { + sprintf(result, "OS/2 error %d", err); + } + + return result; } 1.2 +3 -2 apache-apr/pthreads/src/os/tpf/Makefile.tmpl Index: Makefile.tmpl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/tpf/Makefile.tmpl,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- Makefile.tmpl 1999/01/21 23:08:40 1.1 +++ Makefile.tmpl 1999/06/10 06:26:39 1.2 @@ -3,7 +3,7 @@ INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES) LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS) -OBJS= os.o os-inline.o ebcdic.o +OBJS= os.o os-inline.o ebcdic.o cgetop.o LIB= libos.a @@ -35,7 +35,8 @@ && rm Makefile.new $(OBJS): Makefile -os.o: os.c os-inline.c +os.o: os.c os-inline.c $(INCDIR)/ap_config.h ebcdic.o: ebcdic.c +cgetop.o: cgetop.c # DO NOT REMOVE os.o: os.c 1.3 +260 -30 apache-apr/pthreads/src/os/tpf/os.c Index: os.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/tpf/os.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- os.c 1999/02/07 06:30:12 1.2 +++ os.c 1999/06/10 06:26:39 1.3 @@ -63,6 +63,11 @@ #include "httpd.h" #include "http_core.h" #include "os.h" +#include "scoreboard.h" +#include "http_log.h" +#include "http_conf_globals.h" + +static FILE *sock_fp; /* Check the Content-Type to decide if conversion is needed */ int ap_checkconv(struct request_rec *r) @@ -87,14 +92,22 @@ if (type && (strncasecmp(type, "text/", 5) == 0 || strncasecmp(type, "message/", 8) == 0)) { if (strncasecmp(type, ASCIITEXT_MAGIC_TYPE_PREFIX, - sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1) == 0) + sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1) == 0){ r->content_type = ap_pstrcat(r->pool, "text/", - type+sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1, - NULL); + type+sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1, NULL); + if (r->method_number == M_PUT) + ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, 0); + } + else /* translate EBCDIC to ASCII */ convert_to_ascii = 1; } + else{ + if (r->method_number == M_PUT) + ap_bsetflag(r->connection->client, B_ASCII2EBCDIC, 0); + /* don't translate non-text files to EBCDIC */ + } /* Enable conversion if it's a text document */ ap_bsetflag(r->connection->client, B_EBCDIC2ASCII, convert_to_ascii); @@ -103,51 +116,58 @@ int tpf_select(int maxfds, fd_set *reads, fd_set *writes, fd_set *excepts, struct timeval *tv) { - int sockets[24]; +/* We're going to force our way through select. We're only interested reads and TPF allows + 2billion+ socket descriptors for we don't want an fd_set that big. Just assume that maxfds-1 + contains the socket descriptor we're interested in. If it's 0, leave it alone. */ + + int sockets[1]; int no_reads = 0; int no_writes = 0; int no_excepts = 0; int timeout = 0; - int counter = 0; - int i; - fd_set *temp; + int rv; if(maxfds) { - if(reads) - temp = reads; - else if(writes) - temp = writes; - else if(excepts) - temp = excepts; + if(tv) + timeout = tv->tv_sec * 1000 + tv->tv_usec; + sockets[0] = maxfds-1; + no_reads++; + } else - temp = NULL; + sockets[0] = 0; - for(i=0; i<maxfds; i++) { - if(FD_ISSET(i,temp)) { - sockets[counter] = i; - counter++; - } - } + ap_check_signals(); + rv = select(sockets, no_reads, no_writes, no_excepts, timeout); + ap_check_signals(); - if(tv) - timeout = tv->tv_sec * 1000 + tv->tv_usec; + return rv; - if(reads) - no_reads = counter; - else if(writes) - no_writes = counter; - else if(excepts) - no_excepts = counter; +} + +int tpf_accept(int sockfd, struct sockaddr *peer, int *paddrlen) +{ + int socks[1]; + int rv; + + ap_check_signals(); + socks[0] = sockfd; + rv = select(socks, 1, 0, 0, 1000); + errno = sock_errno(); + if(rv>0) { + ap_check_signals(); + rv = accept(sockfd, peer, paddrlen); + errno = sock_errno(); } - return select(sockets, no_reads, no_writes, no_excepts, timeout); + return rv; } -/* pipe is not yet available on TPF */ +#ifndef __PIPE_ int pipe(int fildes[2]) { errno = ENOSYS; return(-1); } +#endif /* fork and exec functions are not defined on TPF due to the implementation of tpf_fork() */ @@ -175,3 +195,213 @@ errno = ENOSYS; return(-1); } + +int execvp(const char *file, char *const argv[]) +{ + errno = ENOSYS; + return(-1); +} + + + +int ap_tpf_spawn_child(pool *p, int (*func) (void *, child_info *), + void *data, enum kill_conditions kill_how, + int *pipe_in, int *pipe_out, int *pipe_err, + int out_fds[], int in_fds[], int err_fds[]) + +{ + + int i, temp_out, temp_in, temp_err, save_errno, pid, result=0; + int fd_flags_out, fd_flags_in, fd_flags_err; + struct tpf_fork_input fork_input; + TPF_FORK_CHILD *cld = (TPF_FORK_CHILD *) data; + array_header *env_arr = ap_table_elts ((array_header *) cld->subprocess_env); + table_entry *elts = (table_entry *) env_arr->elts; + + + + if (func) { + if (result=func(data, NULL)) { + return 0; /* error from child function */ + } + } + + if (pipe_out) { + fd_flags_out = fcntl(out_fds[0], F_GETFD); + fcntl(out_fds[0], F_SETFD, FD_CLOEXEC); + temp_out = dup(STDOUT_FILENO); + fcntl(temp_out, F_SETFD, FD_CLOEXEC); + dup2(out_fds[1], STDOUT_FILENO); + } + + + if (pipe_in) { + fd_flags_in = fcntl(in_fds[1], F_GETFD); + fcntl(in_fds[1], F_SETFD, FD_CLOEXEC); + temp_in = dup(STDIN_FILENO); + fcntl(temp_in, F_SETFD, FD_CLOEXEC); + dup2(in_fds[0], STDIN_FILENO); + } + + if (pipe_err) { + fd_flags_err = fcntl(err_fds[0], F_GETFD); + fcntl(err_fds[0], F_SETFD, FD_CLOEXEC); + temp_err = dup(STDERR_FILENO); + fcntl(temp_err, F_SETFD, FD_CLOEXEC); + dup2(err_fds[1], STDERR_FILENO); + } + + if (cld->subprocess_env) { + for (i = 0; i < env_arr->nelts; ++i) { + if (!elts[i].key) + continue; + setenv (elts[i].key, elts[i].val, 1); + } + } + + fork_input.program = (const char*) cld->filename; + fork_input.prog_type = cld->prog_type; + fork_input.istream = TPF_FORK_IS_BALANCE; + fork_input.ebw_data_length = 0; + fork_input.ebw_data = NULL; + fork_input.parm_data = NULL; + + + if ((pid = tpf_fork(&fork_input)) < 0) { + save_errno = errno; + if (pipe_out) { + close(out_fds[0]); + } + if (pipe_in) { + close(in_fds[1]); + } + if (pipe_err) { + close(err_fds[0]); + } + errno = save_errno; + pid = 0; + } + + if (cld->subprocess_env) { + for (i = 0; i < env_arr->nelts; ++i) { + if (!elts[i].key) + continue; + unsetenv (elts[i].key); + } + } + + if (pipe_out) { + close(out_fds[1]); + dup2(temp_out, STDOUT_FILENO); + close(temp_out); + fcntl(out_fds[0], F_SETFD, fd_flags_out); + } + + if (pipe_in) { + close(in_fds[0]); + dup2(temp_in, STDIN_FILENO); + close(temp_in); + fcntl(in_fds[1], F_SETFD, fd_flags_in); + } + + + if (pipe_err) { + close(err_fds[1]); + dup2(temp_err, STDERR_FILENO); + close(temp_err); + fcntl(err_fds[0], F_SETFD, fd_flags_err); + } + + + if (pid) { + + ap_note_subprocess(p, pid, kill_how); + + if (pipe_out) { + *pipe_out = out_fds[0]; + } + if (pipe_in) { + *pipe_in = in_fds[1]; + } + if (pipe_err) { + *pipe_err = err_fds[0]; + } + } + + return pid; + +} + +pid_t os_fork(server_rec *s, int slot) +{ + struct tpf_fork_input fork_input; + APACHE_TPF_INPUT input_parms; + int count; + listen_rec *lr; + + fflush(stdin); + if (dup2(fileno(sock_fp), STDIN_FILENO) == -1) + ap_log_error(APLOG_MARK, APLOG_CRIT, s, + "unable to replace stdin with sock device driver"); + fflush(stdout); + if (dup2(fileno(sock_fp), STDOUT_FILENO) == -1) + ap_log_error(APLOG_MARK, APLOG_CRIT, s, + "unable to replace stdout with sock device driver"); + input_parms.generation = ap_my_generation; +#ifdef SCOREBOARD_FILE + input_parms.scoreboard_fd = scoreboard_fd; +#else /* must be USE_TPF_SCOREBOARD or USE_SHMGET_SCOREBOARD */ + input_parms.scoreboard_heap = ap_scoreboard_image; +#endif + + lr = ap_listeners; + count = 0; + do { + input_parms.listeners[count] = lr->fd; + lr = lr->next; + count++; + } while(lr != ap_listeners); + + input_parms.slot = slot; + input_parms.restart_time = ap_restart_time; + fork_input.ebw_data = &input_parms; + fork_input.program = ap_server_argv0; + fork_input.prog_type = TPF_FORK_NAME; + fork_input.istream = TPF_FORK_IS_BALANCE; + fork_input.ebw_data_length = sizeof(input_parms); + fork_input.parm_data = "-x"; + return tpf_fork(&fork_input); +} + +int os_check_server(char *server) { + #ifndef USE_TPF_DAEMON + int rv; + int *current_acn; + if((rv = inetd_getServerStatus(server)) == INETD_SERVER_STATUS_INACTIVE) + return 1; + else { + current_acn = (int *)cinfc_fast(CINFC_CMMACNUM); + if(ecbp2()->ce2acn != *current_acn) + return 1; + } + #endif + return 0; +} + +void os_note_additional_cleanups(pool *p, int sd) { + char sockfilename[50]; + /* write the socket to file so that TPF socket device driver will close socket in case + we happen to abend. */ + sprintf(sockfilename, "/dev/tpf.socket.file/%.8X", sd); + sock_fp = fopen(sockfilename, "r+"); + ap_note_cleanups_for_file(p, sock_fp); /* arrange to close on exec or restart */ + fcntl(sd,F_SETFD,FD_CLOEXEC); +} + +void os_tpf_child(APACHE_TPF_INPUT *input_parms) { + tpf_child = 1; + ap_my_generation = input_parms->generation; + ap_restart_time = input_parms->restart_time; +} + + 1.3 +51 -55 apache-apr/pthreads/src/os/tpf/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/tpf/os.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- os.h 1999/02/07 06:30:12 1.2 +++ os.h 1999/06/10 06:26:39 1.3 @@ -20,9 +20,6 @@ * part of the header */ #define INLINE extern ap_inline - -INLINE int ap_os_is_path_absolute(const char *file); - #include "os-inline.c" #endif @@ -30,82 +27,81 @@ /* Compiler does not support inline, so prototype the inlineable functions * as normal */ -extern int ap_os_is_path_absolute(const char *file); +extern int ap_os_is_path_absolute(const char *f); #endif /* Other ap_os_ routines not used by this platform */ #define ap_os_is_filename_valid(f) (1) +#define ap_os_kill(pid, sig) kill(pid, sig) /* Sorry if this is ugly, but the include order doesn't allow me * to use request_rec here... */ struct request_rec; extern int ap_checkconv(struct request_rec *r); -#ifdef FD_SETSIZE -#undef FD_SETSIZE -#endif +#include <strings.h> +#ifndef __strings_h #define FD_SETSIZE 2048 -#ifdef __FD_MASK -#undef __FD_MASK -#endif - -typedef long __FD_MASK; - -#ifdef __NBBY -#undef __NBBY -#endif - -#define __NBBY 8 /* number of bits in a byte */ - -#ifdef __NFDBITS -#undef __NFDBITS -#endif +typedef long fd_mask; -#define __NFDBITS (sizeof(__FD_MASK) * __NBBY) +#define NBBY 8 /* number of bits in a byte */ +#define NFDBITS (sizeof(fd_mask) * NBBY) +#define howmany(x, y) (((x)+((y)-1))/(y)) -#ifndef __howmany -#define __howmany(x, y) (((x)+((y)-1))/(y)) -#endif - typedef struct fd_set { - __FD_MASK fds_bits [__howmany(FD_SETSIZE, __NFDBITS)]; + fd_mask fds_bits [howmany(FD_SETSIZE, NFDBITS)]; } fd_set; -#define FD_SET(n, p)((p)->fds_bits[(n)/__NFDBITS] |= (1 <<((n) % __NFDBITS))) - -#define FD_CLR(n, p)((p)->fds_bits[(n)/__NFDBITS] &= ~(1 << ((n) % __NFDBITS))) - -#define FD_ISSET(n, p)((p)->fds_bits[(n)/__NFDBITS] & (1 <<((n) % __NFDBITS))) - +#define FD_CLR(n, p)((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p)((p)->fds_bits[(n)/NFDBITS] & (1 <<((n) % NFDBITS))) #define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p))) +#endif +#ifdef FD_SET +#undef FD_SET +#define FD_SET(n, p) (0) +#endif -#define SIGPIPE 13 -#define SIGQUIT 24 -#define SO_KEEPALIVE 0x0008 +#define RESOURCE_KEY ((void*) 0xC1C2C1C3) /* TPF doesn't have, or need, tzset (it is used in mod_expires.c) */ #define tzset() - -#include <stdarg.h> -#undef va_list -#undef va_start -#undef va_arg -#undef va_end - -typedef char *va_list; -#define __va_promote(type) (((sizeof(type) + sizeof(int) - 1) \ - / sizeof(int)) * sizeof(int)) +#include <i$netd.h> +struct apache_input { + INETD_SERVER_INPUT inetd_server; + void *scoreboard_heap; /* scoreboard system heap address */ + int scoreboard_fd; /* scoreboard file descriptor */ + int slot; /* child number */ + int generation; /* server generation number */ + int listeners[10]; + time_t restart_time; +}; -#define va_start(ap, last) (ap = ((char *)&(last) + __va_promote(last))) +typedef struct apache_input APACHE_TPF_INPUT; -#define va_arg(ap, type) ((type *)(ap += sizeof(type) < sizeof(int) ? \ - (abort(), 0) : sizeof(type)))[-1] +typedef struct tpf_fork_child { + char *filename; + enum { FORK_NAME = 1, FORK_FILE = 2 } prog_type; + void *subprocess_env; +}TPF_FORK_CHILD; -#define va_end(ap) +int tpf_accept(int sockfd, struct sockaddr *peer, int *paddrlen); +extern int tpf_child; +struct server_rec; +pid_t os_fork(struct server_rec *s, int slot); +int os_check_server(char *server); +extern char *ap_server_argv0; +extern int scoreboard_fd; +#include <signal.h> +#ifndef SIGPIPE +#define SIGPIPE 14 +#endif +#ifdef NSIG +#undef NSIG +#endif #endif /*! APACHE_OS_H*/ 1.2 +15 -8 apache-apr/pthreads/src/os/unix/os.c Index: os.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/unix/os.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- os.c 1999/01/21 23:08:40 1.1 +++ os.c 1999/06/10 06:26:40 1.2 @@ -26,8 +26,15 @@ * dynamic shared object (DSO) mechanism */ -#ifdef RHAPSODY +#ifdef HAVE_DYLD /* NeXT/Apple dynamic linker */ #include <mach-o/dyld.h> + +/* + * NSUnlinkModule() is a noop in old versions of dyld. + * Let's install an error handler to deal with "multiply defined + * symbol" runtime errors. + */ +#ifdef DYLD_CANT_UNLOAD #include "httpd.h" #include "http_log.h" @@ -49,7 +56,6 @@ * every time we reload a module. Workaround here is to just * rebind to the new symbol, and forget about the old one. * This is crummy, because it's basically a memory leak. - * (See Radar 2262020 against dyld). */ #ifdef DEBUG @@ -73,11 +79,12 @@ abort(); } -#endif /*RHAPSODY*/ +#endif /* DYLD_CANT_UNLOAD */ +#endif /* HAVE_DYLD */ void ap_os_dso_init(void) { -#if defined(RHAPSODY) +#if defined(HAVE_DYLD) && defined(DYLD_CANT_UNLOAD) NSLinkEditErrorHandlers handlers; handlers.undefined = undefined_symbol_handler; @@ -95,7 +102,7 @@ handle = shl_load(path, BIND_IMMEDIATE|BIND_VERBOSE|BIND_NOSTART, 0L); return (void *)handle; -#elif defined(RHAPSODY) +#elif defined(HAVE_DYLD) NSObjectFileImage image; if (NSCreateObjectFileImageFromFile(path, &image) != NSObjectFileImageSuccess) @@ -116,7 +123,7 @@ #if defined(HPUX) || defined(HPUX10) shl_unload((shl_t)handle); -#elif defined(RHAPSODY) +#elif defined(HAVE_DYLD) NSUnLinkModule(handle,FALSE); #else @@ -138,7 +145,7 @@ status = shl_findsym((shl_t *)&handle, symname, TYPE_DATA, &symaddr); return (status == -1 ? NULL : symaddr); -#elif defined(RHAPSODY) +#elif defined(HAVE_DYLD) NSSymbol symbol; char *symname2 = (char*)malloc(sizeof(char)*(strlen(symname)+2)); sprintf(symname2, "_%s", symname); @@ -163,7 +170,7 @@ { #if defined(HPUX) || defined(HPUX10) return strerror(errno); -#elif defined(RHAPSODY) +#elif defined(HAVE_DYLD) return NULL; #else return dlerror(); 1.6 +3 -0 apache-apr/pthreads/src/os/unix/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/unix/os.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -u -r1.5 -r1.6 --- os.h 1999/04/09 03:33:39 1.5 +++ os.h 1999/06/10 06:26:40 1.6 @@ -60,7 +60,9 @@ #include "ap_config.h" +#ifndef PLATFORM #define PLATFORM "Unix" +#endif /* * This file in included in all Apache source code. It contains definitions @@ -92,6 +94,7 @@ /* Other ap_os_ routines not used by this platform */ #define ap_os_is_filename_valid(f) (1) +#define ap_os_kill(pid, sig) kill(pid, sig) /* * Abstraction layer for loading 1.5 +3 -0 apache-apr/pthreads/src/os/win32/os.h Index: os.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/os.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- os.h 1999/03/17 17:02:06 1.4 +++ os.h 1999/06/10 06:26:41 1.5 @@ -123,4 +123,7 @@ #define ap_os_dso_sym(h,s) GetProcAddress(h,s) #define ap_os_dso_error() "" /* for now */ +/* Other ap_os_ routines not used by this platform */ +#define ap_os_kill(pid, sig) kill(pid, sig) + #endif /* ! APACHE_OS_H */ 1.3 +116 -40 apache-apr/pthreads/src/os/win32/registry.c Index: registry.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/registry.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- registry.c 1999/02/07 06:30:15 1.2 +++ registry.c 1999/06/10 06:26:41 1.3 @@ -15,6 +15,16 @@ * release to a development or beta version. */ +/* To allow for multiple services, store the configuration file's full path + * under each service entry: + * + * HKLM\System\CurrentControlSet\Services\[service name]\Parameters\ConfPath + * + * The default configuration path (for console apache) is still stored: + * + * HKLM\Software\[Vendor]\[Software]\[Version]\ServerRoot + */ + #include <windows.h> #include <stdio.h> @@ -28,10 +38,13 @@ #define VENDOR "Apache Group" #define SOFTWARE "Apache" -#define VERSION "1.3.5 dev" +#define VERSION "1.3.7 dev" #define REGKEY "SOFTWARE\\" VENDOR "\\" SOFTWARE "\\" VERSION +#define SERVICEKEYPRE "System\\CurrentControlSet\\Services\\" +#define SERVICEKEYPOST "\\Parameters" + /* * The Windows API registry key functions don't set the last error * value (the windows equivalent of errno). So we need to set it @@ -79,7 +92,7 @@ * message will be logged at priority "warning". */ -static int ap_registry_get_key_int(pool *p, char *key, char *pBuffer, int nSizeBuffer, char **ppValue) +static int ap_registry_get_key_int(pool *p, char *key, char *name, char *pBuffer, int nSizeBuffer, char **ppValue) { long rv; HKEY hKey; @@ -88,19 +101,18 @@ int retval; rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REGKEY, + key, 0, KEY_READ, &hKey); if (rv == ERROR_FILE_NOT_FOUND) { ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, - "Registry does not contain key " REGKEY); + "Registry does not contain key %s",key); return -1; } if (rv != ERROR_SUCCESS) { - do_error(rv, "RegOpenKeyEx HKLM\\" REGKEY, - NULL); + do_error(rv, "RegOpenKeyEx HKLM\\%s",key); return -4; } @@ -110,7 +122,7 @@ * buffer if the return value is ERROR_SUCCESS. */ rv = RegQueryValueEx(hKey, - key, /* key name */ + name, /* key name */ NULL, /* reserved */ NULL, /* type */ NULL, /* for value */ @@ -139,7 +151,7 @@ } rv = RegQueryValueEx(hKey, - key, /* key name */ + name, /* key name */ NULL, /* reserved */ NULL, /* type */ pValue, /* for value */ @@ -149,7 +161,7 @@ if (rv == ERROR_FILE_NOT_FOUND) { ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, - "Registry does not contain value " REGKEY "\\%s", key); + "Registry does not contain value %s\\%s", key, name); retval = -1; } else if (rv == ERROR_MORE_DATA) { @@ -169,7 +181,7 @@ rv = RegCloseKey(hKey); if (rv != ERROR_SUCCESS) { - do_error(rv, "RegCloseKey HKLM\\" REGKEY, NULL); + do_error(rv, "RegCloseKey HKLM\\%s", key); if (retval == 0) { /* Keep error status from RegQueryValueEx, if any */ retval = -4; @@ -191,7 +203,7 @@ { int rv; - rv = ap_registry_get_key_int(p, "ServerRoot", dir, size, NULL); + rv = ap_registry_get_key_int(p, REGKEY, "ServerRoot", dir, size, NULL); if (rv < 0) { dir[0] = '\0'; } @@ -199,10 +211,61 @@ return (rv < -1) ? -1 : 0; } +char *ap_get_service_key(char *service_name) +{ + char *key = malloc(strlen(SERVICEKEYPRE) + + strlen(service_name) + + strlen(SERVICEKEYPOST) + 1); + + sprintf(key,"%s%s%s", SERVICEKEYPRE, service_name, SERVICEKEYPOST); + + return(key); +} + +int ap_registry_get_service_conf(pool *p, char *dir, int size, char *service_name) +{ + int rv; + char *key = ap_get_service_key(service_name); + + rv = ap_registry_get_key_int(p, key, "ConfPath", dir, size, NULL); + if (rv < 0) { + dir[0] = '\0'; + } + + free(key); + return (rv < -1) ? -1 : 0; +} + /********************************************************************** * The rest of this file deals with storing keys or values in the registry */ +char *ap_registry_parse_key(int index, char *key) +{ + char *head = key, *skey; + int i; + + if(!key) + return(NULL); + + for(i = 0; i <= index; i++) + { + if(key && key[0] == '\\') + key++; + if (!key) + return(NULL); + head = key; + key = strchr(head, '\\'); + } + + if(!key) + return(strdup(head)); + *key = '\0'; + skey = strdup(head); + *key = '\\'; + return(skey); +} + /* * ap_registry_create_apache_key() creates the Apache registry key * (HLKM\SOFTWARE\Apache Group\Apache\version, as defined at the start @@ -215,31 +278,25 @@ * already have been logged. */ -static int ap_registry_create_apache_key(void) +static int ap_registry_create_key(char *longkey) { - static char *keys[] = - { "SOFTWARE", - VENDOR, - SOFTWARE, - VERSION, - NULL - }; int index; HKEY hKey; HKEY hKeyNext; int retval; int rv; + char *key; hKey = HKEY_LOCAL_MACHINE; index = 0; retval = 0; /* Walk the tree, creating at each stage if necessary */ - while (keys[index]) { + while (key=ap_registry_parse_key(index,longkey)) { int result; rv = RegCreateKeyEx(hKey, - keys[index], /* subkey */ + key, /* subkey */ 0, /* reserved */ NULL, /* class */ REG_OPTION_NON_VOLATILE, @@ -248,7 +305,7 @@ &hKeyNext, &result); if (rv != ERROR_SUCCESS) { - do_error(rv, "RegCreateKeyEx(%s)", keys[index]); + do_error(rv, "RegCreateKeyEx(%s)", longkey); retval = -4; } @@ -266,11 +323,12 @@ break; } + free(key); hKey = hKeyNext; index++; } - if (keys[index] == NULL) { + if (!key) { /* Close the final key we opened, if we walked the entire * tree */ @@ -283,6 +341,8 @@ } } } + else + free(key); return retval; } @@ -302,14 +362,14 @@ * logged via aplog_error(). */ -static int ap_registry_store_key_int(char *key, DWORD type, void *value, int value_size) +static int ap_registry_store_key_int(char *key, char *name, DWORD type, void *value, int value_size) { long rv; HKEY hKey; int retval; rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REGKEY, + key, 0, KEY_WRITE, &hKey); @@ -317,7 +377,7 @@ if (rv == ERROR_FILE_NOT_FOUND) { /* Key could not be opened -- try to create it */ - if (ap_registry_create_apache_key() < 0) { + if (ap_registry_create_key(key) < 0) { /* Creation failed (error already reported) */ return -4; } @@ -325,28 +385,26 @@ /* Now it has been created we should be able to open it */ rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - REGKEY, + key, 0, KEY_WRITE, &hKey); if (rv == ERROR_FILE_NOT_FOUND) { - ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, - "Registry does not contain key " REGKEY " after creation"); - + ap_log_error(APLOG_MARK,APLOG_WARNING|APLOG_NOERRNO,NULL, + "Registry does not contain key %s after creation",key); return -1; } } if (rv != ERROR_SUCCESS) { - do_error(rv, "RegOpenKeyEx HKLM\\" REGKEY, - NULL); - return -4; + do_error(rv, "RegOpenKeyEx HKLM\\%s", key); + return -4; } /* Now set the value and data */ rv = RegSetValueEx(hKey, - key, /* value key name */ + name, /* value key name */ 0, /* reserved */ type, /* type */ value, /* value data */ @@ -369,17 +427,34 @@ */ rv = RegCloseKey(hKey); if (rv != ERROR_SUCCESS) { - do_error(rv, "RegCloseKey HKLM\\" REGKEY, NULL); - if (retval == 0) { - /* Keep error status from RegQueryValueEx, if any */ - retval = -4; - } + do_error(rv, "RegCloseKey HKLM\\%s", key); + if (retval == 0) { + /* Keep error status from RegQueryValueEx, if any */ + retval = -4; + } } return retval; } /* + * Sets the service confpath value within the registry. Returns 0 on success + * or -1 on error. If -1 is return the error will already have been + * logged via aplog_error(). + */ + +int ap_registry_set_service_conf(char *conf, char *service_name) +{ + int rv; + char *key = ap_get_service_key(service_name); + + rv = ap_registry_store_key_int(key, "ConfPath", REG_SZ, conf, strlen(conf)+1); + free(key); + + return rv < 0 ? -1: 0; +} + +/* * Sets the serverroot value within the registry. Returns 0 on success * or -1 on error. If -1 is return the error will already have been * logged via aplog_error(). @@ -389,7 +464,8 @@ { int rv; - rv = ap_registry_store_key_int("ServerRoot", REG_SZ, dir, strlen(dir)+1); + rv = ap_registry_store_key_int(REGKEY, "ServerRoot", REG_SZ, dir, strlen(dir)+1); return rv < 0 ? -1 : 0; } + 1.2 +2 -0 apache-apr/pthreads/src/os/win32/registry.h Index: registry.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/registry.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- registry.h 1999/01/21 23:08:41 1.1 +++ registry.h 1999/06/10 06:26:41 1.2 @@ -4,3 +4,5 @@ extern int ap_registry_get_server_root(pool *p, char *dir, int size); extern int ap_registry_set_server_root(char *dir); +extern int ap_registry_get_service_conf(pool *p, char *dir, int size, char *service_name); +extern int ap_registry_set_service_conf(char *dir, char *service_name); 1.2 +183 -68 apache-apr/pthreads/src/os/win32/service.c Index: service.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/service.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- service.c 1999/01/21 23:08:41 1.1 +++ service.c 1999/06/10 06:26:41 1.2 @@ -26,59 +26,35 @@ FILE *logFile; } globdat; -static void WINAPI service_main_fn(DWORD, char **); +static void WINAPI service_main_fn(DWORD, LPTSTR *); static void WINAPI service_ctrl(DWORD ctrlCode); static int ReportStatusToSCMgr(int currentState, int exitCode, int waitHint); -static void InstallService(); -static void RemoveService(); - +static int ap_start_service(SC_HANDLE); +static int ap_stop_service(SC_HANDLE); -int service_main(int (*main_fn)(int, char **), int argc, char **argv, - char *service_name, - int install_flag, int run_as_service) +int service_main(int (*main_fn)(int, char **), int argc, char **argv ) { SERVICE_TABLE_ENTRY dispatchTable[] = { - { service_name, service_main_fn }, + { "", service_main_fn }, { NULL, NULL } }; - globdat.name = service_name; + globdat.main_fn = main_fn; + globdat.stop_event = create_event(0, 0, "apache-signal"); + globdat.connected = 1; - if(install_flag > 0) - { - InstallService(); - return(0); - } - else if(install_flag < 0) + if(!StartServiceCtrlDispatcher(dispatchTable)) { - RemoveService(); - return(0); + /* This is a genuine failure of the SCM. */ + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "Error starting service control dispatcher"); + return(globdat.exit_status); } else { - globdat.main_fn = main_fn; - globdat.stop_event = create_event(0, 0, "apache-signal"); - - if(run_as_service) - { - globdat.connected = 1; - if(!StartServiceCtrlDispatcher(dispatchTable)) - { - return((*main_fn)(argc, argv)); - } - else - { - return(globdat.exit_status); - } - } - else - { - globdat.connected = 0; - return((*main_fn)(argc, argv)); - } + return(globdat.exit_status); } - } void service_cd() @@ -90,25 +66,27 @@ chdir(buf); } -void __stdcall service_main_fn(DWORD argc, char **argv) +void __stdcall service_main_fn(DWORD argc, LPTSTR *argv) { - + ap_server_argv0 = globdat.name = argv[0]; if(!(globdat.hServiceStatus = RegisterServiceCtrlHandler( globdat.name, service_ctrl))) { - globdat.exit_status = -1; + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "Failure registering service handler"); return; } - ReportStatusToSCMgr( SERVICE_START_PENDING, // service state NO_ERROR, // exit code 3000); // wait hint - - globdat.exit_status = (*globdat.main_fn)( argc, argv ); - + service_cd(); + if( service_init() ) + /* Arguments are ok except for \! */ + globdat.exit_status = (*globdat.main_fn)( argc, argv ); + ReportStatusToSCMgr(SERVICE_STOPPED, NO_ERROR, 0); return; @@ -206,21 +184,26 @@ } return(1); } - -void InstallService() +void InstallService(char *service_name, char *conf) { SC_HANDLE schService; SC_HANDLE schSCManager; TCHAR szPath[512]; + TCHAR szQuotedPath[512]; + + printf("Installing the %s service to use %s\n", service_name, conf); if (GetModuleFileName( NULL, szPath, 512 ) == 0) { - exit(1); + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "GetModuleFileName failed"); return; } + ap_snprintf(szQuotedPath, 512, "\"%s\"", szPath); + schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) @@ -233,13 +216,13 @@ else { schService = CreateService( schSCManager, // SCManager database - globdat.name, // name of service - globdat.name, // name to display + service_name, // name of service + service_name, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type - szPath, // service's binary + szQuotedPath, // service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // dependencies @@ -249,8 +232,9 @@ if (schService) { CloseServiceHandle(schService); - /* Now store the server_root in the registry */ - ap_registry_set_server_root(ap_server_root); + /* Now store the server_root in the registry */ + if(!ap_registry_set_service_conf(conf, service_name)) + printf("The %s service has been installed successfully.\n", service_name ); } else { ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, @@ -259,17 +243,16 @@ CloseServiceHandle(schSCManager); } - } - - -void RemoveService() +void RemoveService(char *service_name) { SC_HANDLE schService; SC_HANDLE schSCManager; + printf("Removing the %s service\n", service_name); + schSCManager = OpenSCManager( NULL, // machine (NULL == local) NULL, // database (NULL == default) @@ -280,7 +263,7 @@ "OpenSCManager failed"); } else { - schService = OpenService(schSCManager, globdat.name, SERVICE_ALL_ACCESS); + schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS); if (schService == NULL) { /* Could not open the service */ @@ -289,28 +272,160 @@ } else { /* try to stop the service */ - if (ControlService(schService, SERVICE_CONTROL_STOP, &globdat.ssStatus)) { - Sleep(1000); - while(QueryServiceStatus(schService, &globdat.ssStatus)) { - if(globdat.ssStatus.dwCurrentState == SERVICE_STOP_PENDING) - Sleep(1000); - else - break; - } - } + ap_stop_service(schService); // now remove the service if (DeleteService(schService) == 0) ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, "DeleteService failed"); + else + printf("The %s service has been removed successfully.\n", service_name ); CloseServiceHandle(schService); } + /* SCM removes registry parameters */ + CloseServiceHandle(schSCManager); + } + +} +/* A hack to determine if we're running as a service without waiting for + * the SCM to fail; if AllocConsole succeeds, we're a service. + */ + +BOOL isProcessService() { + if( !AllocConsole() ) + return FALSE; + FreeConsole(); + return TRUE; +} + +/* Determine is service_name is a valid service + */ + +BOOL isValidService(char *service_name) { + SC_HANDLE schSCM, schSVC; + int Err; + + if (!(schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "OpenSCManager failed"); + return FALSE; + } + + if ((schSVC = OpenService(schSCM, service_name, SERVICE_ALL_ACCESS))) { + CloseServiceHandle(schSVC); + CloseServiceHandle(schSCM); + return TRUE; + } + + Err = GetLastError(); + if (Err != ERROR_SERVICE_DOES_NOT_EXIST && Err != ERROR_INVALID_NAME) + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "OpenService failed"); + + return FALSE; +} + +int send_signal_to_service(char *service_name, char *sig) { + SC_HANDLE schService; + SC_HANDLE schSCManager; + int success = FALSE; + + enum { start, restart, stop, unknown } action; + static char *param[] = { "start", "restart", "shutdown" }; + static char *participle[] = { "starting", "restarting", "stopping" }; + static char *past[] = { "started", "restarted", "stopped" }; + + for (action = start; action < unknown; action++) + if (!strcasecmp(sig, param[action])) + break; + + if (action == unknown) { + printf("signal must be start, restart, or shutdown\n"); + return FALSE; + } + + schSCManager = OpenSCManager( + NULL, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS // access required + ); + if (!schSCManager) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "OpenSCManager failed"); + } + else { + schService = OpenService(schSCManager, service_name, SERVICE_ALL_ACCESS); + + if (schService == NULL) { + /* Could not open the service */ + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "OpenService failed"); + } + else { + if (!QueryServiceStatus(schService, &globdat.ssStatus)) + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_WIN32ERROR, NULL, + "QueryService failed"); + else { + if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED && action == stop) + printf("The %s service is not started.\n", service_name); + else if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING && action == start) + printf("The %s service has already been started.\n", service_name); + else { + printf("The %s service is %s.\n", service_name, participle[action]); + + if (action == stop || action == restart) + success = ap_stop_service(schService); + if (action == start || action == restart) + success = ap_start_service(schService); + + if( success ) + printf("The %s service has %s.\n", service_name, past[action]); + else + printf("Failed to %s the %s service.\n", sig, service_name ); + } + + CloseServiceHandle(schService); + } + } + /* SCM removes registry parameters */ CloseServiceHandle(schSCManager); } + return success; +} +int ap_stop_service(SC_HANDLE schService) +{ + if (ControlService(schService, SERVICE_CONTROL_STOP, &globdat.ssStatus)) { + Sleep(1000); + while (QueryServiceStatus(schService, &globdat.ssStatus)) { + if (globdat.ssStatus.dwCurrentState == SERVICE_STOP_PENDING) + Sleep(1000); + else + break; + } + } + if (QueryServiceStatus(schService, &globdat.ssStatus)) + if (globdat.ssStatus.dwCurrentState == SERVICE_STOPPED) + return TRUE; + return FALSE; } +int ap_start_service(SC_HANDLE schService) { + if (StartService(schService, 0, NULL)) { + Sleep(1000); + while(QueryServiceStatus(schService, &globdat.ssStatus)) { + if(globdat.ssStatus.dwCurrentState == SERVICE_START_PENDING) + Sleep(1000); + else + break; + } + } + if (QueryServiceStatus(schService, &globdat.ssStatus)) + if (globdat.ssStatus.dwCurrentState == SERVICE_RUNNING) + return TRUE; + return FALSE; +} + #endif /* WIN32 */ - 1.2 +7 -3 apache-apr/pthreads/src/os/win32/service.h Index: service.h =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/service.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -u -r1.1 -r1.2 --- service.h 1999/01/21 23:08:41 1.1 +++ service.h 1999/06/10 06:26:41 1.2 @@ -3,11 +3,15 @@ #define SERVICE_H #ifdef WIN32 -int service_main(int (*main_fn)(int, char **), int argc, char **argv, - char *service_name, - int install_flag, int run_as_service); +int service_main(int (*main_fn)(int, char **), int argc, char **argv); void service_set_status(int status); void service_cd(); +BOOL isProcessService(); +BOOL isValidService(char *service_name); +void InstallService(char *service_name, char *conf); +void RemoveService(char *service_name); +int service_init(); +int send_signal_to_service(char *service_name, char *sig); #endif /* WIN32 */ #endif /* SERVICE_H */ 1.3 +102 -64 apache-apr/pthreads/src/os/win32/installer/apache.iwz Index: apache.iwz =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/os/win32/installer/apache.iwz,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- apache.iwz 1999/02/07 06:30:17 1.2 +++ apache.iwz 1999/06/10 06:26:43 1.3 @@ -36,7 +36,6 @@ Version=2.02 DevTool=Generic Windows Platform=Win32 -DisksBuilt=1 DisksDir=apache\650MB\ TabsVisit=1111001110000111100011 LangNum=451 @@ -46,9 +45,9 @@ AppName=Apache AppExe= AppExeFile= -Version=1.3.5 dev +Version=1.3.7 dev Company=Apache Group -Title=Apache Web Server 1.3.5 dev +Title=Apache Web Server 1.3.7 dev TitleType=1 BackgrndBmp= BackgrndAlign=4 @@ -72,18 +71,18 @@ [Components] Components=6 -Component1Groups=5 +Component1Groups=6 Component1Name=Application Files Component1Description=Application files needed to run the application -Component1GroupList=1 3 24 25 4 +Component1GroupList=1 3 24 25 4 35 Component2Groups=17 Component2Name=Source Code Component2Description=Source code for Apache and support tools Component2GroupList=10 11 12 13 14 15 16 17 18 19 20 21 22 23 31 32 34 -Component3Groups=5 +Component3Groups=6 Component3Name=Apache Manual Component3Description=Apache documentation -Component3GroupList=5 6 7 8 9 +Component3GroupList=5 6 7 8 9 36 Component4Groups=1 Component4Name=Additional Modules Component4Description=Apache modules to extend the server @@ -98,8 +97,8 @@ Component6GroupList=26 28 29 30 [Groups] -Groups=34 -Group1Size=513790 +Groups=36 +Group1Size=346325 Group1Files=9 Group1Name=Program Executables Group1Dir=<INSTALLDIR> @@ -114,7 +113,7 @@ Group1File7=C:\Apache\README Group1File8=C:\apache\Makefile.tmpl Group1File9=C:\apache\README-NT.TXT -Group2Size=265216 +Group2Size=133120 Group2Files=10 Group2Name=Additional Modules Group2Dir=<INSTALLDIR>\modules @@ -130,7 +129,7 @@ Group2File8=C:\Apache\modules\ApacheModuleStatus.dll Group2File9=C:\Apache\modules\ApacheModuleUserTrack.dll Group2File10=C:\apache\modules\ApacheModuleRewrite.dll -Group3Size=49843 +Group3Size=49860 Group3Files=6 Group3Name=Configuration Files Group3Dir=<INSTALLDIR>\.tmp @@ -150,7 +149,7 @@ Group4TargetOS=-1 Group4File1=C:\Apache\htdocs\index.html Group4File2=C:\apache\htdocs\apache_pb.gif -Group5Size=284610 +Group5Size=295033 Group5Files=34 Group5Name=Manual Group5Dir=<INSTALLDIR>\htdocs\manual @@ -204,7 +203,7 @@ Group6File6=C:\apache\htdocs\manual\images\mod_rewrite_fig1.gif Group6File7=C:\apache\htdocs\manual\images\mod_rewrite_fig2.fig Group6File8=C:\apache\htdocs\manual\images\mod_rewrite_fig2.gif -Group7Size=323537 +Group7Size=329371 Group7Files=22 Group7Name=misc Group7Dir=[Manual]\misc @@ -232,7 +231,7 @@ Group7File20=C:\Apache\htdocs\manual\misc\vif-info.html Group7File21=C:\Apache\htdocs\manual\misc\windoz_keepalive.html Group7File22=C:\apache\htdocs\manual\misc\HTTP_Features.tsv -Group8Size=540126 +Group8Size=558131 Group8Files=48 Group8Name=mod Group8Dir=[Manual]\mod @@ -286,7 +285,7 @@ Group8File46=C:\Apache\htdocs\manual\mod\mod_userdir.html Group8File47=C:\Apache\htdocs\manual\mod\mod_usertrack.html Group8File48=C:\apache\htdocs\manual\mod\mod_mmap_static.html -Group9Size=109856 +Group9Size=112629 Group9Files=13 Group9Name=vhosts Group9Dir=[Manual]\vhosts @@ -305,7 +304,7 @@ Group9File11=C:\Apache\htdocs\manual\vhosts\vhosts-in-depth.html Group9File12=C:\Apache\htdocs\manual\vhosts\virtual-host.html Group9File13=C:\apache\htdocs\manual\vhosts\mass.html -Group10Size=509499 +Group10Size=523748 Group10Files=19 Group10Name=src Group10Dir=<INSTALLDIR>\src @@ -330,7 +329,7 @@ Group10File17=C:\apache\src\BUILD.NOTES Group10File18=C:\apache\src\Makefile_win32.txt Group10File19=C:\apache\src\Makefile_win32_debug.txt -Group11Size=88267 +Group11Size=92924 Group11Files=10 Group11Name=ap Group11Dir=[src]\ap @@ -346,7 +345,7 @@ Group11File8=C:\Apache\src\ap\Makefile.tmpl Group11File9=C:\apache\src\ap\ap_fnmatch.c Group11File10=C:\apache\src\ap\ap_md5c.c -Group12Size=253660 +Group12Size=255397 Group12Files=29 Group12Name=include Group12Dir=[src]\include @@ -381,7 +380,7 @@ Group12File27=C:\apache\src\include\ap_config.h Group12File28=C:\apache\src\include\ap_ctype.h Group12File29=C:\apache\src\include\ap_mmn.h -Group13Size=772778 +Group13Size=789788 Group13Files=22 Group13Name=main Group13Dir=[src]\main @@ -440,7 +439,7 @@ Group17Update=0 Group17TargetOS=-1 Group17File1=C:\Apache\src\modules\extra\Makefile.tmpl -Group18Size=204884 +Group18Size=205708 Group18Files=11 Group18Name=proxy Group18Dir=[modules]\proxy @@ -457,7 +456,7 @@ Group18File9=C:\apache\src\modules\proxy\proxy_ftp.c Group18File10=C:\apache\src\modules\proxy\proxy_http.c Group18File11=C:\apache\src\modules\proxy\proxy_util.c -Group19Size=861166 +Group19Size=863524 Group19Files=36 Group19Name=standard Group19Dir=[modules]\standard @@ -530,48 +529,48 @@ Group20File23=C:\Apache\src\regex\tests Group20File24=C:\Apache\src\regex\utils.h Group20File25=C:\Apache\src\regex\WHATSNEW -Group21Size=195047 +Group21Size=210232 Group21Files=28 Group21Name=support Group21Dir=[src]\support Group21Update=0 Group21TargetOS=-1 -Group21File1=C:\apache\src\support\ab.1 -Group21File2=C:\apache\src\support\ab.c -Group21File3=C:\apache\src\support\apachectl -Group21File4=C:\apache\src\support\apachectl.1 -Group21File5=C:\apache\src\support\apxs.8 -Group21File6=C:\apache\src\support\apxs.pl -Group21File7=C:\apache\src\support\dbmmanage -Group21File8=C:\apache\src\support\dbmmanage.1 -Group21File9=C:\apache\src\support\htdigest.1 -Group21File10=C:\apache\src\support\htdigest.c -Group21File11=C:\apache\src\support\htpasswd.1 -Group21File12=C:\apache\src\support\htpasswd.c -Group21File13=C:\apache\src\support\httpd.8 -Group21File14=C:\apache\src\support\log_server_status -Group21File15=C:\apache\src\support\logresolve.8 -Group21File16=C:\apache\src\support\logresolve.c -Group21File17=C:\apache\src\support\logresolve.pl -Group21File18=C:\apache\src\support\Makefile.tmpl -Group21File19=C:\apache\src\support\phf_abuse_log.cgi -Group21File20=C:\apache\src\support\rotatelogs.8 -Group21File21=C:\apache\src\support\rotatelogs.c -Group21File22=C:\apache\src\support\split-logfile -Group21File23=C:\apache\src\support\suexec.8 -Group21File24=C:\apache\src\support\suexec.c -Group21File25=C:\apache\src\support\suexec.h -Group21File26=C:\apache\src\support\httpd.exp -Group21File27=C:\apache\src\support\htpasswd.dsp -Group21File28=C:\apache\src\support\htpasswd.mak +Group21File1=C:\apache\src\support\ab.c +Group21File2=C:\apache\src\support\apachectl +Group21File3=C:\apache\src\support\apxs.8 +Group21File4=C:\apache\src\support\apxs.pl +Group21File5=C:\apache\src\support\dbmmanage +Group21File6=C:\apache\src\support\dbmmanage.1 +Group21File7=C:\apache\src\support\htdigest.1 +Group21File8=C:\apache\src\support\htdigest.c +Group21File9=C:\apache\src\support\htpasswd.1 +Group21File10=C:\apache\src\support\htpasswd.c +Group21File11=C:\apache\src\support\httpd.8 +Group21File12=C:\apache\src\support\log_server_status +Group21File13=C:\apache\src\support\logresolve.8 +Group21File14=C:\apache\src\support\logresolve.c +Group21File15=C:\apache\src\support\logresolve.pl +Group21File16=C:\apache\src\support\Makefile.tmpl +Group21File17=C:\apache\src\support\phf_abuse_log.cgi +Group21File18=C:\apache\src\support\rotatelogs.8 +Group21File19=C:\apache\src\support\rotatelogs.c +Group21File20=C:\apache\src\support\split-logfile +Group21File21=C:\apache\src\support\suexec.8 +Group21File22=C:\apache\src\support\suexec.c +Group21File23=C:\apache\src\support\suexec.h +Group21File24=C:\apache\src\support\httpd.exp +Group21File25=C:\apache\src\support\htpasswd.dsp +Group21File26=C:\apache\src\support\htpasswd.mak +Group21File27=C:\apache\src\support\ab.8 +Group21File28=C:\apache\src\support\apachectl.8 Group22Size=0 Group22Files=0 Group22Name=os Group22Dir=[src]\os Group22Update=0 Group22TargetOS=-1 -Group23Size=207380 -Group23Files=43 +Group23Size=210812 +Group23Files=46 Group23Name=win32 Group23Dir=[os]\win32 Group23Update=0 @@ -619,7 +618,10 @@ Group23File41=C:\apache\src\os\win32\service.c Group23File42=C:\apache\src\os\win32\service.h Group23File43=C:\apache\src\os\win32\util_win32.c -Group24Size=54784 +Group23File44=C:\apache\src\os\win32\apache.ico +Group23File45=C:\apache\src\os\win32\apache.rc +Group23File46=C:\apache\src\os\win32\resource.h +Group24Size=84480 Group24Files=1 Group24Name=Installer DLL Group24Dir=<INSTALLDIR> @@ -740,7 +742,7 @@ Group30Dir=<INSTALLDIR>\cgi-bin Group30Update=0 Group30TargetOS=-1 -Group31Size=35569 +Group31Size=37002 Group31Files=2 Group31Name=installer Group31Dir=[win32]\installer @@ -748,7 +750,7 @@ Group31TargetOS=-1 Group31File1=C:\apache\src\os\win32\installer\apache.iwz Group31File2=C:\apache\src\os\win32\installer\README.TXT -Group32Size=24684 +Group32Size=30356 Group32Files=4 Group32Name=installdll Group32Dir=[installer]\installdll @@ -797,7 +799,7 @@ Group33File31=C:\apache\icons\small\patch.gif Group33File32=C:\apache\icons\small\ps.gif Group33File33=C:\apache\icons\small\doc.gif -Group34Size=17312 +Group34Size=21478 Group34Files=8 Group34Name=test Group34Dir=[installdll]\test @@ -811,6 +813,20 @@ Group34File6=C:\apache\src\os\win32\installer\installdll\test\test.ico Group34File7=C:\apache\src\os\win32\installer\installdll\test\test.mak Group34File8=C:\apache\src\os\win32\installer\installdll\test\test.rc +Group35Size=58368 +Group35Files=1 +Group35Name=bin +Group35Dir=<INSTALLDIR>\bin +Group35Update=0 +Group35TargetOS=-1 +Group35File1=C:\apache\bin\htpasswd.exe +Group36Size=7223 +Group36Files=1 +Group36Name=search +Group36Dir=[manual]\search +Group36Update=0 +Group36TargetOS=-1 +Group36File1=C:\apache\htdocs\manual\search\manual-index.cgi [Sequence] DestinationLocationDir=<ProgramFilesDir>\Apache Group\Apache @@ -875,7 +891,7 @@ Reg9Val1Name=(Default) Reg9Val1Data=(value not set) Reg9Vals=1 -Reg10Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.5 dev +Reg10Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.7 dev Reg10Val1Type=0 Reg10Val1Name=(Default) Reg10Val1Data=(value not set) @@ -889,20 +905,20 @@ Reg1Path=HKEY_LOCAL_MACHINE\SOFTWARE Reg2Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group Reg3Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache -Reg4Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.5 dev -Reg5Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.5 dev +Reg4Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.7 dev +Reg5Path=HKEY_LOCAL_MACHINE\SOFTWARE\Apache Group\Apache\1.3.7 dev Reg5ValName=ServerRoot Reg5ValType=0 Reg5ValData=<INSTALLDIR> Regs=5 [Icons] -Icons=3 -Icon1Param=-d "<INSTALLDIR>" +Icons=5 +Icon1Param=-d "<INSTALLDIR>" -s Icon1Cmd=[Program Executables]\Apache.exe -Icon1Description=Apache Server +Icon1Description=Start Apache as console app Icon1WorkingDir=[Program Executables] -Icon1IconFile= +Icon1IconFile=[Program Executables]\Apache.exe Icon1RealFile=C:\Apache\Apache.exe Icon1WhichIcon=0 Icon1KeyVirtual=0 @@ -931,12 +947,34 @@ Icon3KeyFlags=0 Icon3StartMenu=0 Icon3Window=0 +Icon4Param=-d "<INSTALLDIR>" -u +Icon4Cmd=[Program Executables]\Apache.exe +Icon4Description=Uninstall Apache Service (NT only) +Icon4WorkingDir=[Program Executables] +Icon4IconFile= +Icon4RealFile=C:\Apache\Apache.exe +Icon4WhichIcon=0 +Icon4KeyVirtual=0 +Icon4KeyFlags=0 +Icon4StartMenu=0 +Icon4Window=0 +Icon5Param=-d "<INSTALLDIR>" -k shutdown +Icon5Cmd=[Program Executables]\Apache.exe +Icon5Description=Shutdown Apache console app +Icon5WorkingDir=[Program Executables] +Icon5IconFile= +Icon5RealFile=C:\Apache\Apache.exe +Icon5WhichIcon=0 +Icon5KeyVirtual=0 +Icon5KeyFlags=0 +Icon5StartMenu=0 +Icon5Window=0 [VisualBasic] PRJFile= [Ext] -Ext1Dlg=Exit Install +Ext1Dlg=Setup Complete Ext1Param1=[Installer DLL]\install.dll Ext1Param2=BeforeExit Ext1Op=DLL 1.4 +157 -32 apache-apr/pthreads/src/support/ab.c Index: ab.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/ab.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -u -r1.3 -r1.4 --- ab.c 1999/03/17 17:02:10 1.3 +++ ab.c 1999/06/10 06:26:45 1.4 @@ -81,6 +81,7 @@ ** - Cleaned up by Ralf S. Engelschall <[EMAIL PROTECTED]>, March 1998 ** - POST and verbosity by Kurt Sussman <[EMAIL PROTECTED]>, August 1998 ** - HTML table output added by David N. Welton <[EMAIL PROTECTED]>, January 1999 + ** - Added Cookie, Arbitrary header and auth support. <[EMAIL PROTECTED]>, April 199 ** */ @@ -120,11 +121,20 @@ #include <string.h> #define ap_select select -#else /* (!)NO_APACHE_INCLUDES */ +#else /* (!)NO_APACHE_INCLUDES */ #include "ap_config.h" +#ifdef CHARSET_EBCDIC +#include "ebcdic.h" +#endif #include <fcntl.h> #include <sys/time.h> -#endif /* NO_APACHE_INCLUDES */ + +#ifndef NO_WRITEV +#include <sys/types.h> +#include <sys/uio.h> +#endif + +#endif /* NO_APACHE_INCLUDES */ /* ------------------- DEFINITIONS -------------------------- */ /* maximum number of requests on a time limited test */ @@ -146,7 +156,8 @@ char cbuff[CBUFFSIZE]; /* a buffer to store server response header */ int cbx; /* offset in cbuffer */ int keepalive; /* non-zero if a keep-alive request */ - int gotheader; /* non-zero if we have the entire header in cbuff */ + int gotheader; /* non-zero if we have the entire header in + * cbuff */ struct timeval start, connect, done; }; @@ -174,6 +185,10 @@ char *postdata; /* *buffer containing data from postfile */ int postlen = 0; /* length of data to be POSTed */ char content_type[1024]; /* content type to put in POST header */ +char cookie[1024], /* optional cookie line */ + auth[1024], /* optional (basic/uuencoded) + * authentification */ + hdrs[4096]; /* optional arbitrary headers */ int port = 80; /* port number */ int use_html = 0; /* use html in the report */ @@ -223,20 +238,85 @@ exit(errno); } +/* -- simple uuencode, lifted from main/util.c which + * needed the pool, so duplicated here with normal + * malloc. + */ +static const char basis_64[] = +"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static char *uuencode(char *string) +{ + int i, len = strlen(string); + char *p; + char *encoded = (char *) malloc((len + 2) / 3 * 4 + 1); + p = encoded; +#ifndef CHARSET_EBCDIC + for (i = 0; i < len-2; i += 3) { + *p++ = basis_64[(string[i] >> 2) & 0x3F]; + *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; + *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int) (string[i + 2] & 0xC0) >> 6)]; + *p++ = basis_64[string[i + 2] & 0x3F]; + } + if (i < len) { + *p++ = basis_64[(string[i] >> 2) & 0x3F]; + *p++ = basis_64[((string[i] & 0x3) << 4) | ((int) (string[i + 1] & 0xF0) >> 4)]; + if (i == (len-2)) + *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; + else + *p++ = '='; + *p++ = '='; + } +#else /*CHARSET_EBCDIC*/ + for (i = 0; i < len-2; i += 3) { + *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; + *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) | ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; + *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) | ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)]; + *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F]; + } + if (i < len) { + *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F]; + *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) | ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)]; + if (i == (len-2)) + *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)]; + else + *p++ = '='; + *p++ = '='; + } +#endif /*CHARSET_EBCDIC*/ + *p = '\0'; + return encoded; +} + /* --------------------------------------------------------- */ /* write out request to a connection - assumes we can write (small) request out in one go into our new socket buffer */ -static void write_request(struct connection *c) +static void write_request(struct connection * c) { +#ifndef NO_WRITEV + struct iovec out[2]; int outcnt = 1; +#endif gettimeofday(&c->connect, 0); - /* XXX: this could use writev for posting -- more efficient -djg */ - write(c->fd, request, reqlen); +#ifndef NO_WRITEV + out[0].iov_base = request; + out[0].iov_len = reqlen; + if (posting) { - write(c->fd, postdata, postlen); + out[1].iov_base = postdata; + out[1].iov_len = postlen; + outcnt = 2; totalposted += (reqlen + postlen); } + writev(c->fd,out, outcnt); +#else + write(c->fd,request,reqlen); + if (posting) { + write(c->fd,postdata,postlen); + totalposted += (reqlen + postlen); + } +#endif c->state = STATE_READ; FD_SET(c->fd, &readbits); @@ -469,7 +549,7 @@ /* start asnchronous non-blocking connection */ -static void start_connect(struct connection *c) +static void start_connect(struct connection * c) { c->read = 0; c->bread = 0; @@ -484,7 +564,7 @@ nonblock(c->fd); gettimeofday(&c->start, 0); - if (connect(c->fd, (struct sockaddr *) &server, sizeof(server)) < 0) { + if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) { if (errno == EINPROGRESS) { c->state = STATE_CONNECTING; FD_SET(c->fd, &writebits); @@ -508,7 +588,7 @@ /* close down connection and save stats */ -static void close_connection(struct connection *c) +static void close_connection(struct connection * c) { if (c->read == 0 && c->keepalive) { /* server has legitimately shut down an idle keep alive request */ @@ -548,7 +628,7 @@ /* read data from connection */ -static void read_connection(struct connection *c) +static void read_connection(struct connection * c) { int r; char *part; @@ -570,13 +650,14 @@ if (!c->gotheader) { char *s; int l = 4; - int space = CBUFFSIZE - c->cbx - 1; /* -1 to allow for 0 terminator */ + int space = CBUFFSIZE - c->cbx - 1; /* -1 to allow for 0 + * terminator */ int tocopy = (space < r) ? space : r; #ifndef CHARSET_EBCDIC - memcpy(c->cbuff + c->cbx, buffer, space); -#else /*CHARSET_EBCDIC */ - ascii2ebcdic(c->cbuff + c->cbx, buffer, space); -#endif /*CHARSET_EBCDIC */ + memcpy(c->cbuff + c->cbx, buffer, tocopy); +#else /* CHARSET_EBCDIC */ + ascii2ebcdic(c->cbuff + c->cbx, buffer, tocopy); +#endif /* CHARSET_EBCDIC */ c->cbx += tocopy; space -= tocopy; c->cbuff[c->cbx] = 0; /* terminate for benefit of strstr */ @@ -584,8 +665,10 @@ printf("LOG: header received:\n%s\n", c->cbuff); } s = strstr(c->cbuff, "\r\n\r\n"); - /* this next line is so that we talk to NCSA 1.5 which blatantly breaks - the http specifaction */ + /* + * this next line is so that we talk to NCSA 1.5 which blatantly + * breaks the http specification + */ if (!s) { s = strstr(c->cbuff, "\n\n"); l = 2; @@ -620,10 +703,12 @@ *q = 0; } - /* XXX: this parsing isn't even remotely HTTP compliant... - * but in the interest of speed it doesn't totally have to be, - * it just needs to be extended to handle whatever servers - * folks want to test against. -djg */ + /* + * XXX: this parsing isn't even remotely HTTP compliant... but in + * the interest of speed it doesn't totally have to be, it just + * needs to be extended to handle whatever servers folks want to + * test against. -djg + */ /* check response code */ part = strstr(c->cbuff, "HTTP"); /* really HTTP/1.x_ */ @@ -732,29 +817,31 @@ if (!posting) { sprintf(request, "GET %s HTTP/1.0\r\n" "User-Agent: ApacheBench/%s\r\n" - "%s" + "%s" "%s" "%s" "Host: %s\r\n" "Accept: */*\r\n" - "\r\n", + "\r\n" "%s", path, VERSION, keepalive ? "Connection: Keep-Alive\r\n" : "", - hostname); + cookie, auth, hostname, hdrs); } else { sprintf(request, "POST %s HTTP/1.0\r\n" "User-Agent: ApacheBench/%s\r\n" - "%s" + "%s" "%s" "%s" "Host: %s\r\n" "Accept: */*\r\n" "Content-length: %d\r\n" "Content-type: %s\r\n" + "%s" "\r\n", path, VERSION, keepalive ? "Connection: Keep-Alive\r\n" : "", + cookie, auth, hostname, postlen, - (content_type[0]) ? content_type : "text/plain"); + (content_type[0]) ? content_type : "text/plain", hdrs); } if (verbosity >= 2) @@ -764,7 +851,7 @@ #ifdef CHARSET_EBCDIC ebcdic2ascii(request, request, reqlen); -#endif /*CHARSET_EBCDIC */ +#endif /* CHARSET_EBCDIC */ /* ok - lets start */ gettimeofday(&start, 0); @@ -851,6 +938,13 @@ fprintf(stderr, " -x attributes String to insert as table attributes\n"); fprintf(stderr, " -y attributes String to insert as tr attributes\n"); fprintf(stderr, " -z attributes String to insert as td or th attributes\n"); + fprintf(stderr, " -C attribute Add cookie, eg. 'Apache=1234. (repeatable)\n"); + fprintf(stderr, " -H attribute Add Arbitrary header line, eg. 'Accept-Encoding: zop'\n"); + fprintf(stderr, " Inserted after all normal header lines. (repeatable)\n"); + fprintf(stderr, " -A attribute Add Basic WWW Authentication, the attributes\n"); + fprintf(stderr, " are a colon separated username and password.\n"); + fprintf(stderr, " -p attribute Add Basic Proxy Authentication, the attributes\n"); + fprintf(stderr, " are a colon separated username and password.\n"); fprintf(stderr, " -V Print version number and exit\n"); fprintf(stderr, " -k Use HTTP KeepAlive feature\n"); fprintf(stderr, " -h Display usage information (this message)\n"); @@ -929,9 +1023,11 @@ tablestring = ""; trstring = ""; tdstring = "bgcolor=white"; - + cookie[0] = '\0'; + auth[0] = '\0'; + hdrs[0] = '\0'; optind = 1; - while ((c = getopt(argc, argv, "n:c:t:T:p:v:kVhwx:y:z:")) > 0) { + while ((c = getopt(argc, argv, "n:c:t:T:p:v:kVhwx:y:z:C:H:P:A:")) > 0) { switch (c) { case 'n': requests = atoi(optarg); @@ -958,11 +1054,37 @@ break; case 't': tlimit = atoi(optarg); - requests = MAX_REQUESTS; /* need to size data array on something */ + requests = MAX_REQUESTS; /* need to size data array on + * something */ break; case 'T': strcpy(content_type, optarg); break; + case 'C': + strncat(cookie, "Cookie: ", sizeof(cookie)); + strncat(cookie, optarg, sizeof(cookie)); + strncat(cookie, "\r\n", sizeof(cookie)); + break; + case 'A': + /* + * assume username passwd already to be in colon separated form. + */ + strncat(auth, "Authorization: basic ", sizeof(auth)); + strncat(auth, uuencode(optarg), sizeof(auth)); + strncat(auth, "\r\n", sizeof(auth)); + break; + case 'P': + /* + * assume username passwd already to be in colon separated form. + */ + strncat(auth, "Proxy-Authorization: basic ", sizeof(auth)); + strncat(auth, uuencode(optarg), sizeof(auth)); + strncat(auth, "\r\n", sizeof(auth)); + break; + case 'H': + strncat(hdrs, optarg, sizeof(hdrs)); + strncat(hdrs, "\r\n", sizeof(hdrs)); + break; case 'V': copyright(); exit(0); @@ -970,7 +1092,10 @@ case 'w': use_html = 1; break; - /* if any of the following three are used, turn on html output automatically */ + /* + * if any of the following three are used, turn on html output + * automatically + */ case 'x': use_html = 1; tablestring = optarg; 1.5 +1 -1 apache-apr/pthreads/src/support/apachectl Index: apachectl =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/apachectl,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- apachectl 1999/03/17 17:02:10 1.4 +++ apachectl 1999/06/10 06:26:46 1.5 @@ -50,7 +50,7 @@ # check for pidfile if [ -f $PIDFILE ] ; then PID=`cat $PIDFILE` - if [ ! "x$PID" = "x" ] && kill -0 $PID; then + if [ "x$PID" != "x" ] && kill -0 $PID 2>/dev/null ; then STATUS="httpd (pid $PID) running" RUNNING=1 else 1.3 +3 -3 apache-apr/pthreads/src/support/apxs.8 Index: apxs.8 =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/apxs.8,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- apxs.8 1999/02/07 06:30:18 1.2 +++ apxs.8 1999/06/10 06:26:46 1.3 @@ -292,9 +292,9 @@ DSO installation options: .TP 12 .B \-i -This indicates the installation operartion and installs one or more +This indicates the installation operation and installs one or more dynamically shared objects into the -servers +server's .I libexec directory. .TP 12 @@ -304,7 +304,7 @@ .B LoadModule line to Apache's .B httpd.conf -configuration file (only if still no such entry exists). +configuration file (only if no such entry exists yet). .TP 12 .B \-A Same as option 1.3 +82 -16 apache-apr/pthreads/src/support/htdigest.c Index: htdigest.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/htdigest.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- htdigest.c 1999/02/07 06:30:19 1.2 +++ htdigest.c 1999/06/10 06:26:46 1.3 @@ -1,3 +1,59 @@ +/* ==================================================================== + * Copyright (c) 1995-1999 The Apache Group. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * 4. The names "Apache Server" and "Apache Group" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * [EMAIL PROTECTED] + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the Apache Group + * for use in the Apache HTTP server project (http://www.apache.org/)." + * + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Group and was originally based + * on public domain software written at the National Center for + * Supercomputing Applications, University of Illinois, Urbana-Champaign. + * For more information on the Apache Group and the Apache HTTP server + * project, please see <http://www.apache.org/>. + * + */ /****************************************************************************** ****************************************************************************** * NOTE! This program is not safe as a setuid executable! Do not make it @@ -12,29 +68,31 @@ #include "ap_config.h" #include <sys/types.h> -#if defined(MPE) || defined(QNX) +#include "ap.h" +#include "ap_md5.h" +#if defined(MPE) || defined(QNX) || defined(WIN32) #include <signal.h> #else #include <sys/signal.h> #endif -#include "ap_md5.h" +#ifdef WIN32 +#include <conio.h> +#define unlink _unlink +#endif + +#ifdef CHARSET_EBCDIC +#define LF '\n' +#define CR '\r' +#else #define LF 10 #define CR 13 +#endif /* CHARSET_EBCDIC */ #define MAX_STRING_LEN 256 char *tn; -static char *strd(char *s) -{ - char *d; - - d = (char *) malloc(strlen(s) + 1); - strcpy(d, s); - return (d); -} - static void getword(char *word, char *line, char stop) { int x = 0, y; @@ -84,15 +142,23 @@ AP_MD5_CTX context; unsigned char digest[16]; char string[MAX_STRING_LEN]; + char pwin[MAX_STRING_LEN]; + char pwv[MAX_STRING_LEN]; unsigned int i; - pw = strd((char *) getpass("New password:")); - if (strcmp(pw, (char *) getpass("Re-type new password:"))) { + if (ap_getpass("New password: ", pwin, sizeof(pwin)) != 0) { + fprintf(stderr, "password too long"); + exit(5); + } + ap_getpass("Re-type new password: ", pwv, sizeof(pwv)); + if (strcmp(pwin, pwv) != 0) { fprintf(stderr, "They don't match, sorry.\n"); - if (tn) + if (tn) { unlink(tn); + } exit(1); } + pw = pwin; fprintf(f, "%s:%s:", user, realm); /* Do MD5 stuff */ @@ -136,7 +202,7 @@ int found; tn = NULL; - signal(SIGINT, (void (*)()) interrupted); + signal(SIGINT, (void (*)(int)) interrupted); if (argc == 5) { if (strcmp(argv[1], "-c")) usage(); @@ -201,5 +267,5 @@ #endif system(command); unlink(tn); - exit(0); + return 0; } 1.3 +98 -5 apache-apr/pthreads/src/support/htpasswd.1 Index: htpasswd.1 =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/htpasswd.1,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- htpasswd.1 1999/02/07 06:30:19 1.2 +++ htpasswd.1 1999/06/10 06:26:46 1.3 @@ -59,12 +59,33 @@ [ .B \-c ] +[ +.B \-m +] +.I passwdfile +.I username +.br +.B htpasswd +.B \-b +[ +.B \-c +] +[ +.B \-m +] .I passwdfile .I username +.I password .SH DESCRIPTION .B htpasswd is used to create and update the flat-files used to store usernames and password for basic authentication of HTTP users. +If +.B htpasswd +cannot access a file, such as not being able to write to the output +file or not being able to read the file in order to update it, +it returns an error status and makes no changes. +.PP Resources available from the .B httpd Apache web server can be restricted to just the users listed @@ -75,27 +96,99 @@ DBM database see \fBdbmmanage\fP. .PP +.B htpasswd +encrypts passwords using either a version of MD5 modified for Apache, +or the system's \fIcrypt()\fP routine. Files managed by +.B htpasswd +may contain both types of passwords; some user records may have +MD5-encrypted passwords while others in the same file may have passwords +encrypted with \fIcrypt()\fP. +.PP This manual page only lists the command line arguments. For details of the directives necessary to configure user authentication in .B httpd see the Apache manual, which is part of the Apache distribution or can be -found at http://www.apache.org/. +found at <URL:http://www.apache.org/>. .SH OPTIONS +.IP \-b +Use batch mode; \fIi.e.\fP, get the password from the command line +rather than prompting for it. \fBThis option should be used with +extreme care, since the password is clearly visible on the command +line.\fP .IP \-c Create the \fIpasswdfile\fP. If \fIpasswdfile\fP already exists, it -is deleted first. +is rewritten and truncated. .IP \-m Use MD5 encryption for passwords. On Windows, this is the only format supported. .IP \fB\fIpasswdfile\fP Name of the file to contain the user name and password. If \-c is given, this file is created if it does not already exist, -or deleted and recreated if it does exist. +or rewritten and truncated if it does exist. .IP \fB\fIusername\fP The username to create or update in \fBpasswdfile\fP. If -\fIusername\fP does not exist is this file, an entry is added. If it +\fIusername\fP does not exist in this file, an entry is added. If it does exist, the password is changed. +.IP \fB\fIpassword\fP +The plaintext password to be encrypted and stored in the file. Only used +with the \fI-b\fP flag. +.SH EXIT STATUS +.B htpasswd +returns a zero status ("true") if the username and password have +been successfully added or updated in the \fIpasswdfile\fP. +.B htpasswd +returns 1 if it encounters some problem accessing files, 2 if there +was a syntax problem with the command line, 3 if the password was +entered interactively and the verification entry didn't match, 4 if +its operation was interrupted, 5 if a value is too long (username, +filename, password, or final computed record), and 6 if the username +contains illegal characters (see the \fBRESTRICTIONS\fP section). +.SH EXAMPLES +\fBhtpasswd /usr/local/etc/apache/.htpasswd-users jsmith\fP +.IP +Adds or modifies the password for user \fIjsmith\fP. +The user is prompted for the password. If executed +on a Windows system, the password will be encrypted using the +modified Apache MD5 algorithm; otherwise, the system's +\fIcrypt()\fP routine will be used. If the file does not +exist, +.B htpasswd +will do nothing except return an error. +.LP +\fBhtpasswd -c /home/doe/public_html/.htpasswd jane\fP +.IP +Creates a new file and stores a record in it for user \fIjane\fP. +The user is prompted for the password. +If the file exists and cannot be read, or cannot be written, +it is not altered and +.B htpasswd +will display a message and return an error status. +.LP +\fBhtpasswd -mb /usr/web/.htpasswd-all jones Pwd4Steve\fP +.IP +Encrypts the password from the command line (\fIPwd4Steve\fP) using +the MD5 algorithm, and stores it in the specified file. +.LP +.SH SECURITY CONSIDERATIONS +Web password files such as those managed by +.B htpasswd +should \fBnot\fP be within the Web server's URI space -- that is, +they should not be fetchable with a browser. +.PP +The use of the \fI-b\fP option is discouraged, since when it is +used the unencrypted password appears on the command line. +.SH RESTRICTIONS +On the Windows and MPE platforms, passwords encrypted with +.B htpasswd +are limited to no more than 255 characters in length. Longer +passwords will be truncated to 255 characters. +.PP +The MD5 algorithm used by +.B htpasswd +is specific to the Apache software; passwords encrypted using it will not be +usable with other Web servers. +.PP +Usernames are limited to 255 bytes and may not include the character ':'. .SH SEE ALSO .BR httpd(8) -. 1.5 +68 -91 apache-apr/pthreads/src/support/htpasswd.c Index: htpasswd.c =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/htpasswd.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- htpasswd.c 1999/03/17 17:02:11 1.4 +++ htpasswd.c 1999/06/10 06:26:46 1.5 @@ -75,6 +75,7 @@ * 4: Failure; operation interrupted (such as with CTRL/C) * 5: Failure; buffer would overflow (username, filename, or computed * record too long) + * 6: Failure; username contains illegal or reserved characters */ #include "ap_config.h" @@ -107,6 +108,7 @@ #define ERR_PWMISMATCH 3 #define ERR_INTERRUPTED 4 #define ERR_OVERFLOW 5 +#define ERR_BADUSER 6 /* * This needs to be declared statically so the signal handler can @@ -115,17 +117,9 @@ static char *tempfilename; /* - * Duplicate a string into memory malloc()ed for it. + * Get a line of input from the user, not including any terminating + * newline. */ -static char *strd(char *s) -{ - char *d; - - d = (char *) malloc(strlen(s) + 1); - strcpy(d, s); - return (d); -} - static int getline(char *s, int n, FILE *f) { register int i = 0; @@ -168,78 +162,35 @@ } } -#ifdef MPE -/* - * MPE lacks getpass() and a way to suppress stdin echo. So for now, just - * issue the prompt and read the results with echo. (Ugh). - */ - -static char *getpass(const char *prompt) -{ - static char password[81]; - - fputs(prompt, stderr); - gets((char *) &password); - - if (strlen((char *) &password) > 8) { - password[8] = '\0'; - } - - return (char *) &password; -} - -#endif - -#ifdef WIN32 -/* - * Windows lacks getpass(). So we'll re-implement it here. - */ - -static char *getpass(const char *prompt) -{ - static char password[81]; - int n = 0; - - fputs(prompt, stderr); - - while ((password[n] = _getch()) != '\r') { - if (password[n] >= ' ' && password[n] <= '~') { - n++; - printf("*"); - } - else { - printf("\n"); - fputs(prompt, stderr); - n = 0; - } - } - - password[n] = '\0'; - printf("\n"); - - if (n > 8) { - password[8] = '\0'; - } - - return (char *) &password; -} -#endif - /* * Make a password record from the given information. A zero return * indicates success; failure means that the output buffer contains an * error message instead. */ -static int mkrecord(char *user, char *record, size_t rlen, int alg) +static int mkrecord(char *user, char *record, size_t rlen, char *passwd, + int alg) { char *pw; char cpw[120]; char salt[9]; + char pwin[MAX_STRING_LEN]; + char pwv[MAX_STRING_LEN]; - pw = strd((char *) getpass("New password: ")); - if (strcmp(pw, (char *) getpass("Re-type new password: "))) { - ap_cpystrn(record, "password verification error", (rlen - 1)); - return ERR_PWMISMATCH; + if (passwd != NULL) { + pw = passwd; + } + else { + if (ap_getpass("New password: ", pwin, sizeof(pwin)) != 0) { + ap_snprintf(record, (rlen - 1), "password too long (>%d)", + sizeof(pwin) - 1); + return ERR_OVERFLOW; + } + ap_getpass("Re-type new password: ", pwv, sizeof(pwv)); + if (strcmp(pwin, pwv) != 0) { + ap_cpystrn(record, "password verification error", (rlen - 1)); + return ERR_PWMISMATCH; + } + pw = pwin; } (void) srand((int) time((time_t *) NULL)); to64(&salt[0], rand(), 8); @@ -247,17 +198,14 @@ switch (alg) { case ALG_APMD5: - ap_MD5Encode(pw, salt, cpw, sizeof(cpw)); + ap_MD5Encode((const unsigned char *)pw, (const unsigned char *)salt, + cpw, sizeof(cpw)); break; case ALG_CRYPT: ap_cpystrn(cpw, (char *)crypt(pw, salt), sizeof(cpw) - 1); break; } - /* - * Now that we have the smashed password, we don't need the - * plaintext one any more. - */ - free(pw); + /* * Check to see if the buffer is large enough to hold the username, * hash, and delimiters. @@ -274,9 +222,13 @@ static int usage(void) { - fprintf(stderr, "Usage: htpasswd [-cm] passwordfile username\n"); - fprintf(stderr, "The -c flag creates a new file.\n"); - fprintf(stderr, "The -m flag forces MD5 encryption of the password.\n"); + fprintf(stderr, "Usage:\n"); + fprintf(stderr, "\thtpasswd [-cm] passwordfile username\n"); + fprintf(stderr, "\thtpasswd -b[cm] passwordfile username password\n\n"); + fprintf(stderr, " -c Create a new file.\n"); + fprintf(stderr, " -m Force MD5 encryption of the password.\n"); + fprintf(stderr, " -b Use the password from the command line rather "); + fprintf(stderr, "than prompting for it.\n"); fprintf(stderr, "On Windows systems the -m flag is used by default.\n"); return ERR_SYNTAX; } @@ -294,7 +246,7 @@ * Check to see if the specified file can be opened for the given * access. */ -int accessible(char *fname, char *mode) +static int accessible(char *fname, char *mode) { FILE *s; @@ -309,7 +261,7 @@ /* * Return true if a file is readable. */ -int readable(char *fname) +static int readable(char *fname) { return accessible(fname, "r"); } @@ -317,7 +269,7 @@ /* * Return true if the specified file can be opened for write access. */ -int writable(char *fname) +static int writable(char *fname) { return accessible(fname, "a"); } @@ -325,7 +277,7 @@ /* * Return true if the named file exists, regardless of permissions. */ -int exists(char *fname) +static int exists(char *fname) { #ifdef WIN32 struct _stat sbuf; @@ -346,7 +298,7 @@ * Copy from the current position of one file to the current position * of another. */ -void copy_file(FILE *target, FILE *source) +static void copy_file(FILE *target, FILE *source) { static char line[MAX_STRING_LEN]; @@ -364,6 +316,7 @@ FILE *ftemp = NULL; FILE *fpw = NULL; char user[MAX_STRING_LEN]; + char password[MAX_STRING_LEN]; char record[MAX_STRING_LEN]; char line[MAX_STRING_LEN]; char pwfilename[MAX_STRING_LEN]; @@ -371,7 +324,9 @@ int found = 0; int alg = ALG_CRYPT; int newfile = 0; + int noninteractive = 0; int i; + int args_left = 2; tempfilename = NULL; signal(SIGINT, (void (*)(int)) interrupted); @@ -401,6 +356,10 @@ else if (*arg == 'm') { alg = ALG_APMD5; } + else if (*arg == 'b') { + noninteractive++; + args_left++; + } else { return usage(); } @@ -408,10 +367,11 @@ } /* - * Make sure we still have exactly two arguments left (the filename - * and the username). + * Make sure we still have exactly the right number of arguments left + * (the filename, the username, and possibly the password if -b was + * specified). */ - if ((argc - i) != 2) { + if ((argc - i) != args_left) { return usage(); } if (strlen(argv[i]) > (sizeof(pwfilename) - 1)) { @@ -420,10 +380,24 @@ } strcpy(pwfilename, argv[i]); if (strlen(argv[i + 1]) > (sizeof(user) - 1)) { - fprintf(stderr, "%s: username too long\n", argv[0]); + fprintf(stderr, "%s: username too long (>%d)\n", argv[0], + sizeof(user) - 1); return ERR_OVERFLOW; } strcpy(user, argv[i + 1]); + if ((arg = strchr(user, ':')) != NULL) { + fprintf(stderr, "%s: username contains illegal character '%c'\n", + argv[0], *arg); + return ERR_BADUSER; + } + if (noninteractive) { + if (strlen(argv[i + 2]) > (sizeof(password) - 1)) { + fprintf(stderr, "%s: password too long (>%d)\n", argv[0], + sizeof(password) - 1); + return ERR_OVERFLOW; + } + strcpy(password, argv[i + 2]); + } #ifdef WIN32 if (alg == ALG_CRYPT) { @@ -480,7 +454,10 @@ * Any error message text is returned in the record buffer, since * the mkrecord() routine doesn't have access to argv[]. */ - if ((i = mkrecord(user, record, sizeof(record) - 1, alg)) != 0) { + i = mkrecord(user, record, sizeof(record) - 1, + noninteractive ? password : NULL, + alg); + if (i != 0) { fprintf(stderr, "%s: %s\n", argv[0], record); exit(i); } 1.5 +3 -0 apache-apr/pthreads/src/support/httpd.exp Index: httpd.exp =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/httpd.exp,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -u -r1.4 -r1.5 --- httpd.exp 1999/03/17 17:02:11 1.4 +++ httpd.exp 1999/06/10 06:26:46 1.5 @@ -248,6 +248,8 @@ ap_rationalize_mtime ap_read_config ap_read_request +ap_regerror +ap_regexec ap_register_cleanup ap_register_other_child ap_release_mutex @@ -285,6 +287,7 @@ ap_send_mmap ap_send_size ap_server_argv0 +ap_server_config_defines ap_server_confname ap_server_post_read_config ap_server_pre_read_config 1.3 +6 -3 apache-apr/pthreads/src/support/log_server_status Index: log_server_status =================================================================== RCS file: /home/cvs/apache-apr/pthreads/src/support/log_server_status,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -u -r1.2 -r1.3 --- log_server_status 1999/02/07 06:30:20 1.2 +++ log_server_status 1999/06/10 06:26:47 1.3 @@ -67,7 +67,7 @@ # require 'sys/socket.ph'; -$wherelog = "/var/log/graph/"; # Logs will be like "/var/log/graph/960312" +$wherelog = "/var/log/graph/"; # Logs will be like "/var/log/graph/19960312" $server = "localhost"; # Name of server, could be "www.foo.com" $port = "80"; # Port on server $request = "/status/?auto"; # Request to send @@ -93,8 +93,11 @@ ### Main { - $date=`date +%y%m%d:%H%M%S`; - chop($date); + $year=`date +%y`; + chomp($year); + $year += ($year < 70) ? 2000 : 1900; + $date = $year . `date +%m%d:%H%M%S`; + chomp($date); ($day,$time)=split(/:/,$date); $res=&tcp_connect($server,$port); open(OUT,">>$wherelog$day"); 1.1 apache-apr/pthreads/src/support/README Index: README =================================================================== Support files: ab ABuse your server with this benchmarker. Rudimentary command line testing tool. apachectl Apache run-time Control script. To facilitate the administrator and/or your rc.d scripts to control the functioning of the Apache httpd daemon. apxs APache eXtenSion tool. Eases building and installing DSO style modules. dbmmanage Create and update user authentication files in the faster DBM format used by mod_auth_db. htdigest Create and update user authentication files used in DIGEST authentification. See mod_auth_digest. htpasswd Create and update user authentication files used in BASIC authentification. I.e. the htpasswd files. See mod_auth. httpd.8 General apache man page. log_server_status This script is designed to be run at a frequent interval by something like cron. It connects to the server and downloads the status information. It reformats the information to a single line and logs it to a file. logresolve resolve hostnames for IP-adresses in Apache logfiles phf_abuse_log.cgi This script can be used to detect people trying to abuse an ancient and long plugged security hole which existed in a CGI script distributed with Apache 1.0.3 and earlier versions. rotatelogs rotate Apache logs without having to kill the server. split-logfile This script will take a combined virtual hosts access log file and break its contents into separate files. suexec Switch User For Exec. Used internally by apache, see the document `Apache suEXEC Support' under http://www.apache.org/docs/suexec.html . 1.1 apache-apr/pthreads/src/support/ab.8 Index: ab.8 =================================================================== .TH ab 1 "March 1998" .\" $Id: ab.8,v 1.1 1999/06/10 06:26:45 manoj Exp $ .\" Copyright (c) 1998-1999 The Apache Group. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in .\" the documentation and/or other materials provided with the .\" distribution. .\" .\" 3. All advertising materials mentioning features or use of this .\" software must display the following acknowledgment: .\" "This product includes software developed by the Apache Group .\" for use in the Apache HTTP server project (http://www.apache.org/)." .\" .\" 4. The names "Apache Server" and "Apache Group" must not be used to .\" endorse or promote products derived from this software without .\" prior written permission. .\" .\" 5. Products derived from this software may not be called "Apache" .\" nor may "Apache" appear in their names without prior written .\" permission of the Apache Group. .\" .\" 6. Redistributions of any form whatsoever must retain the following .\" acknowledgment: .\" "This product includes software developed by the Apache Group .\" for use in the Apache HTTP server project (http://www.apache.org/)." .\" .\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY .\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR .\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, .\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED .\" OF THE POSSIBILITY OF SUCH DAMAGE. .\" ==================================================================== .\" .\" This software consists of voluntary contributions made by many .\" individuals on behalf of the Apache Group and was originally based .\" on public domain software written at the National Center for .\" Supercomputing Applications, University of Illinois, Urbana-Champaign. .\" For more information on the Apache Group and the Apache HTTP server .\" project, please see <http://www.apache.org/>. .SH NAME ab \- Apache HTTP server benchmarking tool .SH SYNOPSIS .B ab [ .B \-k ] [ .BI \-n " requests" ] [ .BI \-t " timelimit" ] [ .BI \-c " concurrency" ] [ .BI \-p " POST file" ] [ .BI \-A " Authenticate username:password" ] [ .BI \-P " Proxy Authenticate username:password" ] [ .BI \-H " Custom header" ] [ .BI \-C " Cookie name=value" ] [ .BI \-T " content-type" ] [ .BI \-v " verbosity" ] ] [ .BI \-w " output HTML" ] ] [ .BI \-x " <table> attributes" ] ] [ .BI \-y " <tr> attributes" ] ] [ .BI \-z " <td> attributes" ] .I [http://]hostname[:port]/path .B ab [ .B \-V ] [ .B \-h ] .PP .SH DESCRIPTION .B ab is a tool for benchmarking your Apache HyperText Transfer Protocol (HTTP) server. It is designed to give you an impression on how performant is your current Apache installation. This especially shows you how much requests per time your Apache installation is capable to serve. .PP .SH OPTIONS .TP 12 .B \-k Enable the HTTP KeepAlive feature, i.e. perform multiple requests within one HTTP session instead. Default is no KeepAlive. .TP 12 .BI \-n " requests" Number of requests to perform for the benchmarking session. The default is to just perform one single request which usually leads to not very representative benchmarking results. .TP 12 .BI \-t " timelimit" Seconds to max. spend for benchmarking. This implies a .B \-n .B 50000 internally. Use this to benchmark the server within a fixed total amount of time. Per default there is no timelimit. .TP 12 .BI \-c " concurrency" Number of multiple requests per time to perform. Default is one request per time. .TP 12 .BI \-p " POST file" File containing data to POST. .TP 12 .BI \-A " Authorization username:password" Supply BASIC Authentification credentials to the server. The username and password are separated by a single ':' and send on the wire uuencoded. The string is send regardless of wether the server needs it; (i.e. has send an 401. Authentifcation needed). .TP 12 .BI \-p " Proxy-Authorization username:password" Supply BASIC Authentification credentials to a proxy en-route. The username and password are separated by a single ':' and send on the wire uuencoded. The string is send regardless of wether the proxy needs it; (i.e. has send an 407 Proxy authentifcation needed). .TP 12 .BI \-C " Cookie name=value" Add a 'Cookie:' line to the request. The argument is typically in the form of a 'name=value' pair. This field is repeatable. .TP 12 .BI \-p " Header string" Postfix extra headers to the request. The argument is typically in the form of a valid header line; containing a colon separated field value pair. (i.e. 'Accept-Encoding: zip/zop;8bit'). .TP 12 .BI \-T " content-type" Content-type header to use for POST data. .TP 12 .B \-v Set verbosity level - 4 and above prints information on headers, 3 and above prints response codes (404, 200, etc.), 2 and above prints warnings and info. .TP 12 .BI \-w Print out results in HTML tables. Default table is two columns wide, with a white background. .TP 12 .BI \-x " attributes" String to use as attributes for <table>. Attributes are inserted <table .B here > .TP 12 .BI \-y " attributes" String to use as attributes for <tr>. .TP 12 .BI \-z " attributes" String to use as attributes for <td>. .TP 12 .B \-V Display version number and exit. .TP 12 .B \-h Display usage information. .PD .SH BUGS There are various statically declared buffers of fixed length. Combined with the lazy parsing of the command line arguments, the response headers from the server and other external inputs this might bite you. .P It does not implement HTTP/1.x fully; only accepts some 'expected' forms of responses. The rather heavy use of .BR strstr(3) shows up top in profile, which might indicate a performance problem; i.e. you would measure the .BR ab performance rather than the server's. .SH SEE ALSO .BR httpd(8) .