You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ma...@hyperreal.org on 1998/01/14 00:11:33 UTC

cvs commit: apachen/src/os/bs2000 .cvsignore Makefile.tmpl ebcdic.c ebcdic.h os-inline.c os.c os.h

martin      98/01/13 15:11:33

  Modified:    .        CHANGES STATUS
               src      Configure
               src/helpers GuessOS
               src/main buff.c buff.h conf.h http_bprintf.c http_config.c
                        http_core.c http_main.c http_protocol.c httpd.h
                        util.c
               src/modules/standard mod_include.c mod_mime.c mod_rewrite.c
  Added:       src      README.EBCDIC
               src/os/bs2000 .cvsignore Makefile.tmpl ebcdic.c ebcdic.h
                        os-inline.c os.c os.h
  Log:
  This patch adds the changes necessary to make apache compile and run
  on the Siemens Nixdorf BS2000-OSD/POSIX mainframes (EBCDIC charset).
  Reviewed by:	 Dean Gaudet +1, Martin Kraemer +1
  
  Revision  Changes    Path
  1.16      +7 -0      apachen/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/apachen/CHANGES,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -u -r1.15 -r1.16
  --- CHANGES	1997/08/24 13:16:28	1.15
  +++ CHANGES	1998/01/13 23:10:52	1.16
  @@ -113,3 +113,10 @@
          given HTTP request.  If the request is a sub-request or
          internal redirect, the function will return false.
   
  +  *) Apache now ported to a mainframe machine with EBCDIC charset
  +       This new port makes apache-1.3 compile and run on a
  +       Siemens Nixdorf mainframe running under the BS2000-OSD
  +       operating system in the POSIX subsystem. The server is capable
  +       of serving either "binary-ASCII" or EBCDIC coded HTML text
  +       documents. See the file README.EBCDIC in the src directory;
  +       it also explains which modules still need porting (most are ready).
  
  
  
  1.85      +1 -6      apachen/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /home/cvs/apachen/STATUS,v
  retrieving revision 1.84
  retrieving revision 1.85
  diff -u -u -r1.84 -r1.85
  --- STATUS	1998/01/13 22:45:51	1.84
  +++ STATUS	1998/01/13 23:10:53	1.85
  @@ -79,6 +79,7 @@
       * Dean's [PATCH] unneeded pstrdup()s (in table_*() calls)
       * Brian Havard's [Patch] OS/2 - fix up shut down
       * Dean's [PATCH] make mod_rewrite use ap_cpystrn
  +    * Martin's [PORT] Make apache compile & run on an EBCDIC mainframe
   
   Available Patches:
   
  @@ -106,12 +107,6 @@
   	Submitted by: Soeren Ziehe <RO...@AMTRASH.comlink.de>
   	<19...@deejai.mch.sni.de>
   	Status: Martin +1, Dean +1, Jim +1, Soeren +1, Dirk.vanGulik@jrc.it +1
  -
  -    * Martin's [PATCH] 36kB: Make apache compile & run on an EBCDIC mainframe
  -	<19...@deejai.mch.sni.de>
  -	Status: Martin +1, Dean +1
  -	(needs an update I'm sure... I've been running this patch on a linux box
  -	since Martin posted it without troubles -djg)
   
       * Marc's [PATCH] PR#1543: suexec logging exec failures
   	<Pi...@alive.znep.com>
  
  
  
  1.176     +8 -0      apachen/src/Configure
  
  Index: Configure
  ===================================================================
  RCS file: /home/cvs/apachen/src/Configure,v
  retrieving revision 1.175
  retrieving revision 1.176
  diff -u -u -r1.175 -r1.176
  --- Configure	1997/12/21 01:58:53	1.175
  +++ Configure	1998/01/13 23:11:04	1.176
  @@ -454,6 +454,14 @@
   	DEF_WANTHSREGEX=yes
   	LIBS="$LIBS -lsocket -lnsl -lc -lgen"
   	;;
  +    BS2000*-sni-sysv4*)
  +	OS='BS2000'
  +	OSDIR='os/bs2000'
  +	CC='c89'
  +	CFLAGS="$CFLAGS -DCHARSET_EBCDIC -DSVR4 -D_XPG_IV"
  +	DEF_WANTHSREGEX=yes
  +	LIBS="$LIBS -lsocket -lnsl -lc"
  +	;;
       *-sni-sysv4*)
   	OS='SVR4'
   	CFLAGS="$CFLAGS -DSVR4 -D_XPG_IV -DUSE_MMAP_FILES -DUSE_SYSVSEM_SERIALIZED_ACCEPT -DNEED_UNION_SEMUN"
  
  
  
  1.1                  apachen/src/README.EBCDIC
  
  Index: README.EBCDIC
  ===================================================================
  			    README.EBCDIC
  
  This version of Apache comes with a first-cut (working, but not
  fully tested) port to a mainframe machine which uses the EBCDIC
  character set as its native codeset (It is the SIEMENS NIXDORF
  family of mainframes running the BS2000 operating system. This
  mainframe OS nowadays features a SVR4-like POSIX subsystem).
  
  The port was started initially to
  - prove the feasibility
  - find a "worthy and capable" successor for the CERN daemon (which
    was ported a couple of years ago), and to
  - prove that Apache's preforking process model can on this platform
    easily outperform the accept-fork-serve model used by CERN by a
    factor of 5 or more.
  
  This document serves as a rationale to describe some of the design
  decisions of the port to this machine.
  
  * The relevant changes in the source are #ifdef'ed into two
    categories:
    #ifdef CHARSET_EBCDIC     Code which is needed for any EBCDIC
  			    based machine
    #ifdef _OSD_POSIX         Code which is needed for the BS2000
  			    SIEMENS NIXDORF mainframe platform only.
  
  * The possibility to translate between ASCII and EBCDIC at the
    socket level (on BS2000 POSIX, there is a socket option which
    supports this) was intentionally not chosen, because the byte
    stream at the HTTP protocol level consists of a mixture of
    protocol related strings and non-protocol related raw file data.
    HTTP protocol strings are always encoded in ASCII (the GET
    request, any Header: lines, the chunking information etc.) whereas
    the file transfer parts (i.e., GIF images, CGI output etc.) should
    usually be just "passed thru" by the server. This separation
    between "protocol string" and "raw data" is reflected in the
    server code by functions like bgets() or rvputs() for strings, and
    functions like bwrite() for binary data. A global translation of
    everything would therefore be inadequate.
    (In the case of text files of course, provisions must be made so
    that the documents are always served in ASCII format)
  
  * This port therefore features a built-in protocol level conversion
    for the server-internal strings (which the compiler translated to
    EBCDIC strings) and server-generated documents. The hard coded
    ASCII escapes \012 and \015 which are ubiquitious in the server
    code are an exception: they are not converted to ASCII a second
    time.
  
  * For Text documents (MIME types text/plain, text/html etc.), an
    implicit translation to ASCII can be used, or (if the users prefer
    to store some documents in raw ASCII form for faster serving) can
    be served without conversion.
    Example:
        to serve files with the suffix .ahtml as a raw ASCII text/html
        document (and suffix .ascii as ASCII text/plain), use the
        directives:
      AddType  text/x-ascii-html  .ahtml
      AddType  text/x-ascii-plain .ascii
    Similarly, any text/XXXX MIME type can be served as "raw ASCII" by
    configuring a MIME text/x-ascii-XXXX for it.
  
  * Non-text documents are always served "binary" without conversion.
    This seems to be the most sensible choice for, .e.g., GIF/ZIP/AU
    file types.
  
  * Server parsed files are always assumed to be in native (i.e.,
    EBCDIC) format as used on the machine, and are converted after
    processing.
  
  *
  
  What works:
  - In the following list,
      + means: works, tested
      - means: doesn't work for some reason
      ? means: compiled-in, but untested
  
    http_core.c           +
    mod_access.c          +
    mod_actions.c         ?
    mod_alias.c           +
    mod_asis.c            ?
    mod_auth.c            +
    mod_auth_anon.c       +
    mod_auth_db.c         - / no libdb
    mod_auth_dbm.c        - / no libdbm
    mod_autoindex.c       +
    mod_cern_meta.c       ?
    mod_cgi.c             - / exec of scripts via #! doesn't work
    mod_digest.c          - / MD5 not ported yet
    mod_dir.c             +
    mod_dld.c             - / no shared libs
    mod_env.c             +
    mod_example.c         - / not tried yet
    mod_expires.c         +
    mod_headers.c         +
    mod_imap.c            +
    mod_include.c         + / only <!--#exec cgi= doesn't work (see mod_cgi).
    mod_info.c            + / some flaws
    mod_log_agent.c       +
    mod_log_config.c      +
    mod_log_referer.c     +
    mod_mime.c            +
    mod_mime_magic.c      - / not tried yet
    mod_negotiation.c     +
    mod_proxy.c           - / no protocol conversion implemented yet
    mod_rewrite.c         ? / untested
    mod_setenvif.c        +
    mod_so.c              - no shared libs
    mod_speling.c         +
    mod_status.c          +
    mod_unique_id.c       +
    mod_userdir.c         +
    mod_usertrack.c       ?
  
  
  What doesn't work yet:
  -   no DBM or DB authentication (library missing)
  -   no MD5 hash or digest (not ported yet)
  -   no execution of #! scripts (needs porting)
  
  			    Martin Kraemer, 22-Dec-1997
  
  
  
  1.33      +4 -0      apachen/src/helpers/GuessOS
  
  Index: GuessOS
  ===================================================================
  RCS file: /home/cvs/apachen/src/helpers/GuessOS,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -u -r1.32 -r1.33
  --- GuessOS	1997/10/25 01:52:44	1.32
  +++ GuessOS	1998/01/13 23:11:06	1.33
  @@ -199,6 +199,10 @@
   	echo "${MACHINE}-sni-sysv4"; exit 0
   	;;
   
  +    POSIX*BS2000)
  +	echo "${MACHINE}-sni-sysv4"; exit 0
  +	;;
  +
       machten:*)
          echo "${MACHINE}-tenon-${SYSTEM}"; exit 0;
          ;;
  
  
  
  1.56      +89 -4     apachen/src/main/buff.c
  
  Index: buff.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/buff.c,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -u -r1.55 -r1.56
  --- buff.c	1998/01/13 22:51:37	1.55
  +++ buff.c	1998/01/13 23:11:07	1.56
  @@ -419,6 +419,9 @@
   	/* we overwrote the \r, so put it back */
   	fb->outbase[i - 1] = '\015';
       }
  +#ifdef CHARSET_EBCDIC
  +    ebcdic2ascii(&fb->outbase[fb->outchunk], &fb->outbase[fb->outchunk], fb->outchunk_header_size);
  +#endif /*CHARSET_EBCDIC*/
   
       /* tack on the trailing CRLF, we've reserved room for this */
       fb->outbase[fb->outcnt++] = '\015';
  @@ -662,7 +665,7 @@
    * transmission, or -1 on an error.
    *
    * Notes:
  - *  If null characters are exepected in the data stream, then
  + *  If null characters are expected in the data stream, then
    * buff should not be treated as a null terminated C string; instead
    * the returned count should be used to determine the length of the
    * string.
  @@ -702,6 +705,7 @@
   	    continue;		/* restart with the new data */
   	}
   
  +#ifndef CHARSET_EBCDIC
   	ch = fb->inptr[i++];
   	if (ch == '\012') {	/* got LF */
   	    if (ct == 0)
  @@ -722,6 +726,28 @@
   
   	buff[ct++] = ch;
       }
  +#else /* an EBCDIC machine: do the same, but convert to EBCDIC on the fly: */
  +	ch = _toebcdic[(unsigned char)fb->inptr[i++]];
  +	if (ch == _toebcdic['\012']) {	/* got LF */
  +	    if (ct == 0)
  +		buff[ct++] = '\n';
  +/* if just preceeded by CR, replace CR with LF */
  +	    else if (buff[ct - 1] == _toebcdic['\015'])
  +		buff[ct - 1] = '\n';
  +	    else if (ct < n - 1)
  +		buff[ct++] = '\n';
  +	    else
  +		i--;		/* no room for LF */
  +	    break;
  +	}
  +	if (ct == n - 1) {
  +	    i--;		/* push back ch */
  +	    break;
  +	}
  +
  +	buff[ct++] = ch;
  +    }
  +#endif
       fb->incnt -= i;
       fb->inptr += i;
   
  @@ -761,7 +787,11 @@
   	fb->incnt = i;
       }
   
  +#ifndef CHARSET_EBCDIC
       *buff = fb->inptr[0];
  +#else /*CHARSET_EBCDIC*/
  +    *buff = _toebcdic[(unsigned char)fb->inptr[0]];
  +#endif /*CHARSET_EBCDIC*/
       return 1;
   }
   
  @@ -803,14 +833,18 @@
   }
   
   /*
  - * Emtpy the buffer after putting a single character in it
  + * Empty the buffer after putting a single character in it
    */
   API_EXPORT(int) bflsbuf(int c, BUFF *fb)
   {
       char ss[1];
       int rc;
   
  +#ifndef CHARSET_EBCDIC
       ss[0] = c;
  +#else
  +    ss[0] = _toascii[(unsigned char)c];
  +#endif
       rc = bwrite(fb, ss, 1);
       /* We do start_chunk() here so that the bputc macro can be smaller
        * and faster
  @@ -834,7 +868,11 @@
       if (i != 1)
   	return EOF;
       else
  +#ifndef CHARSET_EBCDIC
   	return buf[0];
  +#else /*CHARSET_EBCDIC*/
  +	return _toebcdic[(unsigned char)buf[0]];
  +#endif /*CHARSET_EBCDIC*/
   }
   
   
  @@ -983,9 +1021,12 @@
       vec[0].iov_base = chunksize;
       vec[0].iov_len = ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012",
   				 nbyte);
  +#ifdef CHARSET_EBCDIC
  +    ebcdic2ascii(chunksize, chunksize, strlen(chunksize));
  +#endif /*CHARSET_EBCDIC*/
       vec[1].iov_base = (void *) buf;	/* cast is to avoid const warning */
       vec[1].iov_len = nbyte;
  -    vec[2].iov_base = "\r\n";
  +    vec[2].iov_base = "\015\012";
       vec[2].iov_len = 2;
   
       return writev_it_all(fb, vec, (sizeof(vec) / sizeof(vec[0]))) ? -1 : nbyte;
  @@ -1019,11 +1060,14 @@
   	vec[nvec].iov_base = chunksize;
   	vec[nvec].iov_len = ap_snprintf(chunksize, sizeof(chunksize),
   					"%x\015\012", nbyte);
  +#ifdef CHARSET_EBCDIC
  +	ebcdic2ascii(chunksize, chunksize, strlen(chunksize));
  +#endif /*CHARSET_EBCDIC*/
   	++nvec;
   	vec[nvec].iov_base = (void *) buf;
   	vec[nvec].iov_len = nbyte;
   	++nvec;
  -	vec[nvec].iov_base = "\r\n";
  +	vec[nvec].iov_base = "\015\012";
   	vec[nvec].iov_len = 2;
   	++nvec;
       }
  @@ -1257,17 +1301,54 @@
   	return rc3;
   }
   
  +#ifdef CHARSET_EBCDIC
  +/*
  + * returns the number of bytes written or -1 on error
  + */
  +API_EXPORT(int) bnputs(const char *x, BUFF *fb, size_t amount)
  +{
  +    int i;
  +    const char *endp = &x[amount];
  +    /* @@@FIXME: This probably could use some performance improvement */
  +    for ( ; x < endp; ++x) {
  +	int ch = *x;
  +	/* This test is a workaround: at many places in Apache, the (ASCII)
  +	 * constants \012 and \015 are used in strings in place of \n and \r.
  +	 * In an EBCDIC environment, the rest of the strings is interpreted
  +	 * as EBCDIC characters, so we need the EBCDIC equivalent of \n and \r
  +	 * instead of \012 and \015. So, for the HTTP protocol level, 
  +	 * conversion is limited to characters other than \012 and \015 (in
  +	 * ebcdic2ascii(), I handled it similarly).
  +	 * Of course, on all ASCII based environments, the decision to use
  +	 * \012 and \015 in strings makes perfectly sense, because on, e.g.,
  +	 * OS-9/68k machines (or MACs), \n is compiled to \015
  +	 * (as is \r; the \012 escape must be written \l) which would violate
  +	 * the HTTP protocol.
  +	 */
  +	if (ch == '\012' || ch == '\015')
  +	    ch = _toebcdic[ch];
  +	if (bputc(ch, fb) != 0)
  +	    return -1;
  +    }
  +    return amount;
  +}
  +#endif /*CHARSET_EBCDIC*/
  +
   /*
    * returns the number of bytes written or -1 on error
    */
   API_EXPORT(int) bputs(const char *x, BUFF *fb)
   {
  +#ifndef CHARSET_EBCDIC
       int i, j = strlen(x);
       i = bwrite(fb, x, j);
       if (i != j)
   	return -1;
       else
   	return j;
  +#else /*CHARSET_EBCDIC*/
  +    return bnputs(x, fb, strlen(x));
  +#endif /*CHARSET_EBCDIC*/
   }
   
   /*
  @@ -1285,7 +1366,11 @@
   	if (x == NULL)
   	    break;
   	j = strlen(x);
  +#ifndef CHARSET_EBCDIC
   	i = bwrite(fb, x, j);
  +#else /*CHARSET_EBCDIC*/
  +	i = bputs(x, fb);
  +#endif /*CHARSET_EBCDIC*/
   	if (i != j) {
   	    va_end(v);
   	    return -1;
  
  
  
  1.29      +15 -0     apachen/src/main/buff.h
  
  Index: buff.h
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/buff.h,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -u -r1.28 -r1.29
  --- buff.h	1998/01/07 16:46:01	1.28
  +++ buff.h	1998/01/13 23:11:07	1.29
  @@ -146,6 +146,9 @@
   API_EXPORT(int) bskiplf(BUFF *fb);
   API_EXPORT(int) bwrite(BUFF *fb, const void *buf, int nbyte);
   API_EXPORT(int) bflush(BUFF *fb);
  +#ifdef CHARSET_EBCDIC
  +API_EXPORT(int) bnputs(const char *x, BUFF *fb, size_t amount);
  +#endif /*CHARSET_EBCDIC*/
   API_EXPORT(int) bputs(const char *x, BUFF *fb);
   API_EXPORT(int) bvputs(BUFF *fb,...);
   API_EXPORT_NONSTD(int) bprintf(BUFF *fb, const char *fmt,...)
  @@ -156,6 +159,8 @@
   API_EXPORT(int) bflsbuf(int c, BUFF *fb);
   API_EXPORT(int) bfilbuf(BUFF *fb);
   
  +#ifndef CHARSET_EBCDIC
  +
   #define bgetc(fb)   ( ((fb)->incnt == 0) ? bfilbuf(fb) : \
   		    ((fb)->incnt--, *((fb)->inptr++)) )
   
  @@ -163,6 +168,16 @@
   		     (fb)->outcnt == (fb)->bufsiz) ? bflsbuf(c, (fb)) : \
   		     ((fb)->outbase[(fb)->outcnt++] = (c), 0))
   
  +#else /*CHARSET_EBCDIC*/
  +
  +#define bgetc(fb)   ( ((fb)->incnt == 0) ? bfilbuf(fb) : \
  +		    ((fb)->incnt--, _toebcdic[(unsigned char)*((fb)->inptr++)]) )
  +
  +#define bputc(c, fb) ((((fb)->flags & (B_EOUT|B_WRERR|B_WR)) != B_WR || \
  +		     (fb)->outcnt == (fb)->bufsiz) ? bflsbuf(c, (fb)) : \
  +		     ((fb)->outbase[(fb)->outcnt++] = _toascii[(unsigned char)c], 0))
  +
  +#endif /*CHARSET_EBCDIC*/
   API_EXPORT(int) spawn_child_err_buff(pool *, int (*)(void *), void *,
   		      enum kill_conditions, BUFF **pipe_in, BUFF **pipe_out,
   				     BUFF **pipe_err);
  
  
  
  1.166     +5 -0      apachen/src/main/conf.h
  
  Index: conf.h
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/conf.h,v
  retrieving revision 1.165
  retrieving revision 1.166
  diff -u -u -r1.165 -r1.166
  --- conf.h	1998/01/07 16:46:01	1.165
  +++ conf.h	1998/01/13 23:11:08	1.166
  @@ -444,6 +444,11 @@
   #define HAVE_SYSLOG
   #define NET_SIZE_T size_t
   #define HAVE_SHMGET
  +#ifdef _OSD_POSIX /* BS2000-POSIX mainframe does not have syslog and needs initgroups */
  +#define NEED_INITGROUPS
  +#undef HAVE_SYSLOG
  +#undef HAVE_SHMGET
  +#endif /*_OSD_POSIX*/
   
   #elif defined(UW)
   #define NO_LINGCLOSE
  
  
  
  1.14      +10 -0     apachen/src/main/http_bprintf.c
  
  Index: http_bprintf.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/http_bprintf.c,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -u -r1.13 -r1.14
  --- http_bprintf.c	1997/09/16 00:41:32	1.13
  +++ http_bprintf.c	1998/01/13 23:11:08	1.14
  @@ -95,8 +95,13 @@
   	if (percentPtr == NULL)
   	    percentPtr = fStop;
   	if (percentPtr != f) {
  +#ifndef CHARSET_EBCDIC
   	    if (bwrite(bp, f, percentPtr - f) < 0)
   		goto ErrorReturn;
  +#else
  +	    if (bnputs(f, bp, percentPtr - f) < percentPtr - f)
  +		goto ErrorReturn;
  +#endif
   	    streamCount += percentPtr - f;
   	    f = percentPtr;
   	    if (f == fStop)
  @@ -554,8 +559,13 @@
   	}			/* for (;;) */
   	ap_assert(buffCount < buffLen);
   	if (buffCount > 0) {
  +#ifndef CHARSET_EBCDIC
   	    if (bwrite(bp, buffPtr, buffCount) < 0)
   		goto ErrorReturn;
  +#else /*CHARSET_EBCDIC*/
  +	    if (bnputs(buffPtr, bp, buffCount) != buffCount)
  +		goto ErrorReturn;
  +#endif /*CHARSET_EBCDIC*/
   	    streamCount += buffCount;
   	}
   	else if (buffCount < 0)
  
  
  
  1.93      +8 -0      apachen/src/main/http_config.c
  
  Index: http_config.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/http_config.c,v
  retrieving revision 1.92
  retrieving revision 1.93
  diff -u -u -r1.92 -r1.93
  --- http_config.c	1998/01/11 20:25:03	1.92
  +++ http_config.c	1998/01/13 23:11:09	1.93
  @@ -518,6 +518,14 @@
       if (strrchr(m->name, '\\'))
   	m->name = 1 + strrchr(m->name, '\\');
   
  +#ifdef _OSD_POSIX /* __FILE__="*POSIX(/home/martin/apache/src/modules/standard/mod_info.c)" */
  +    /* We cannot fix the string in-place, because it's const */
  +    if (m->name[strlen(m->name)-1]==')') {
  +	char *tmp = strdup(m->name);	/* FIXME:memory leak, albeit a small one */
  +	tmp[strlen(tmp)-1] = '\0';
  +	m->name = tmp;
  +    }
  +#endif /*_OSD_POSIX*/
   /** XXX: this will be slow if there's lots of add_modules */
       build_method_shortcuts();
   }
  
  
  
  1.146     +31 -0     apachen/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/http_core.c,v
  retrieving revision 1.145
  retrieving revision 1.146
  diff -u -u -r1.145 -r1.146
  --- http_core.c	1998/01/07 16:46:04	1.145
  +++ http_core.c	1998/01/13 23:11:10	1.146
  @@ -1823,6 +1823,9 @@
   #ifdef USE_MMAP_FILES
       caddr_t mm;
   #endif
  +#ifdef CHARSET_EBCDIC
  +    int convert_to_ascii = 0;
  +#endif /*CHARSET_EBCDIC*/
   
       /* This handler has no use for a request body (yet), but we still
        * need to read and discard it if the client sent one.
  @@ -1895,15 +1898,43 @@
   	}
   
   	rangestatus = set_byterange(r);
  +#ifdef CHARSET_EBCDIC
  +	/* 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.
  +	 */
  +
  +	/* Conversion is applied to text/ files only, if ever. */
  +	if (strncmp(r->content_type, "text/", 5)==0) {
  +	    if (strncasecmp(r->content_type, ASCIITEXT_MAGIC_TYPE_PREFIX, sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1) == 0)
  +		r->content_type = pstrcat(r->pool, "text/", r->content_type+sizeof(ASCIITEXT_MAGIC_TYPE_PREFIX)-1, NULL);
  +	    else
  +		/* translate EBCDIC to ASCII */
  +		convert_to_ascii = 1;
  +	}
  +#endif /*CHARSET_EBCDIC*/
   	send_http_header (r);
   	
   	if (!r->header_only) {
   	    if (!rangestatus)
  +#ifdef CHARSET_EBCDIC
  +		if (convert_to_ascii)
  +		    send_fd_length_cnv(f, r, -1, 1);
  +		else
  +#endif /*CHARSET_EBCDIC*/
   		send_fd (f, r);
   	    else {
   		long offset, length;
   		while (each_byterange(r, &offset, &length)) {
   		    fseek(f, offset, SEEK_SET);
  +#ifdef CHARSET_EBCDIC
  +		    if (convert_to_ascii)
  +			send_fd_length_cnv(f, r, length, 1);
  +		    else
  +#endif /*CHARSET_EBCDIC*/
   		    send_fd_length(f, r, length);
   		}
   	    }
  
  
  
  1.268     +2 -0      apachen/src/main/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/http_main.c,v
  retrieving revision 1.267
  retrieving revision 1.268
  diff -u -u -r1.267 -r1.268
  --- http_main.c	1998/01/13 21:19:10	1.267
  +++ http_main.c	1998/01/13 23:11:11	1.268
  @@ -2494,11 +2494,13 @@
   
   #ifndef MPE
   /* MPE does not support SO_REUSEADDR and SO_KEEPALIVE */
  +#ifndef _OSD_POSIX
       if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(int)) < 0) {
   	aplog_error(APLOG_MARK, APLOG_CRIT, server_conf,
   		    "setsockopt: (SO_REUSEADDR)");
   	exit(1);
       }
  +#endif /*_OSD_POSIX*/
       one = 1;
   #ifndef BEOS
   /* BeOS does not support SO_KEEPALIVE */
  
  
  
  1.174     +21 -0     apachen/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/http_protocol.c,v
  retrieving revision 1.173
  retrieving revision 1.174
  diff -u -u -r1.173 -r1.174
  --- http_protocol.c	1998/01/07 16:46:08	1.173
  +++ http_protocol.c	1998/01/13 23:11:12	1.174
  @@ -1614,6 +1614,18 @@
   }
   
   API_EXPORT(long) send_fd_length(FILE *f, request_rec *r, long length)
  +#ifdef CHARSET_EBCDIC
  +{
  +    return send_fd_length_cnv(f, r, length, 0);
  +}
  +
  +API_EXPORT(long) send_fd_cnv(FILE *f, request_rec *r)
  +{
  +    return send_fd_length_cnv(f, r, -1, 1);
  +}
  +
  +API_EXPORT(long) send_fd_length_cnv(FILE *f, request_rec *r, long length, int convert_to_ascii)
  +#endif /*CHARSET_EBCDIC*/
   {
       char buf[IOBUFSIZE];
       long total_bytes_sent = 0;
  @@ -1634,6 +1646,11 @@
                  && ferror(f) && errno == EINTR && !r->connection->aborted)
               continue;
   
  +#ifdef CHARSET_EBCDIC
  +	if (convert_to_ascii)
  +	    ebcdic_to_ascii(buf, buf, n);
  +#endif /*CHARSET_EBCDIC*/
  +
           if (n < 1) {
               break;
           }
  @@ -1885,7 +1902,11 @@
           if (x == NULL)
               break;
           j = strlen(x);
  +#ifndef CHARSET_EBCDIC
           i = bwrite(fb, x, j);
  +#else /*CHARSET_EBCDIC*/
  +        i = bputs(x, fb);
  +#endif /*CHARSET_EBCDIC*/
           if (i != j) {
               va_end(args);
               return -1;
  
  
  
  1.172     +16 -0     apachen/src/main/httpd.h
  
  Index: httpd.h
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/httpd.h,v
  retrieving revision 1.171
  retrieving revision 1.172
  diff -u -u -r1.171 -r1.172
  --- httpd.h	1998/01/07 16:46:18	1.171
  +++ httpd.h	1998/01/13 23:11:13	1.172
  @@ -464,14 +464,30 @@
   #define CGI_MAGIC_TYPE "application/x-httpd-cgi"
   #define INCLUDES_MAGIC_TYPE "text/x-server-parsed-html"
   #define INCLUDES_MAGIC_TYPE3 "text/x-server-parsed-html3"
  +#ifdef CHARSET_EBCDIC
  +#define ASCIITEXT_MAGIC_TYPE_PREFIX "text/x-ascii-" /* Text files whose content-type starts with this are passed thru unconverted */
  +#endif /*CHARSET_EBCDIC*/
   #define MAP_FILE_MAGIC_TYPE "application/x-type-map"
   #define ASIS_MAGIC_TYPE "httpd/send-as-is"
   #define DIR_MAGIC_TYPE "httpd/unix-directory"
   #define STATUS_MAGIC_TYPE "application/x-httpd-status"
   
   /* Just in case your linefeed isn't the one the other end is expecting. */
  +#ifndef CHARSET_EBCDIC
   #define LF 10
   #define CR 13
  +#else /* CHARSET_EBCDIC */
  +#include "ebcdic.h"
  +/* OSD_POSIX uses the EBCDIC charset. The transition ASCII->EBCDIC is done in
  + * the buff package (bread/bputs/bwrite), so everywhere else, we use
  + * "native EBCDIC" CR and NL characters. These are therefore defined as
  + * '\r' and '\n'.
  + * NB: this is not the whole truth - sometimes \015 and \012 are contained
  + * in literal (EBCDIC!) strings, so these are not converted but passed.
  + */
  +#define CR '\r'
  +#define LF '\n'
  +#endif /* CHARSET_EBCDIC */
   
   /* Possible values for request_rec.read_body (set by handling module):
    *    REQUEST_NO_BODY          Send 413 error if message has any body
  
  
  
  1.84      +50 -1     apachen/src/main/util.c
  
  Index: util.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/main/util.c,v
  retrieving revision 1.83
  retrieving revision 1.84
  diff -u -u -r1.83 -r1.84
  --- util.c	1998/01/11 20:25:05	1.83
  +++ util.c	1998/01/13 23:11:14	1.84
  @@ -989,9 +989,19 @@
   {
       register char digit;
   
  +#ifndef CHARSET_EBCDIC
       digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
       digit *= 16;
       digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0'));
  +#else /*CHARSET_EBCDIC*/
  +    char xstr[5];
  +    xstr[0]='0';
  +    xstr[1]='x';
  +    xstr[2]=what[0];
  +    xstr[3]=what[1];
  +    xstr[4]='\0';
  +    digit = _toebcdic[0xFF & strtol(xstr, NULL, 16)];
  +#endif /*CHARSET_EBCDIC*/
       return (digit);
   }
   
  @@ -1081,7 +1091,11 @@
   
       for (x = 0, y = 0; segment[x]; x++, y++) {
   	char c = segment[x];
  +#ifndef CHARSET_EBCDIC
   	if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c > '9')
  +#else /* CHARSET_EBCDIC*/
  +	if (!isalnum(c)
  +#endif /*CHARSET_EBCDIC*/
   	    && ind("$-_.+!*'(),:@&=~", c) == -1) {
   	    c2x(c, &copy[y]);
   	    y += 2;
  @@ -1109,7 +1123,11 @@
       }
       for (; *path; ++path) {
   	char c = *path;
  +#ifndef CHARSET_EBCDIC
   	if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') && (c < '0' || c > '9')
  +#else /* CHARSET_EBCDIC*/
  +	if (!isalnum(c)
  +#endif /*CHARSET_EBCDIC*/
   	    && ind("$-_.+!*'(),:@&=/~", c) == -1) {
   	    c2x(c, s);
   	    s += 3;
  @@ -1285,7 +1303,7 @@
   #ifdef NEED_INITGROUPS
   int initgroups(const char *name, gid_t basegid)
   {
  -#if defined(QNX) || defined(MPE) || defined(BEOS)
  +#if defined(QNX) || defined(MPE) || defined(BEOS) || defined(_OSD_POSIX)
   /* QNX, MPE and BeOS do not appear to support supplementary groups. */
       return 0;
   #else /* ndef QNX */
  @@ -1552,6 +1570,7 @@
       /* Figure out how many characters are in the input buffer.
        * Allocate this many from the per-transaction pool for the result.
        */
  +#ifndef CHARSET_EBCDIC
       bufin = (const unsigned char *) bufcoded;
       while (pr2six[*(bufin++)] <= 63);
       nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
  @@ -1580,6 +1599,36 @@
   	    nbytesdecoded -= 1;
       }
       bufplain[nbytesdecoded] = '\0';
  +#else /*CHARSET_EBCDIC*/
  +    bufin = (const unsigned char *) bufcoded;
  +    while (pr2six[_toascii[(unsigned char)*(bufin++)]] <= 63);
  +    nprbytes = (bufin - (const unsigned char *) bufcoded) - 1;
  +    nbytesdecoded = ((nprbytes + 3) / 4) * 3;
  +
  +    bufplain = palloc(p, nbytesdecoded + 1);
  +    bufout = (unsigned char *) bufplain;
  +
  +    bufin = (const unsigned char *) bufcoded;
  +
  +    while (nprbytes > 0) {
  +	*(bufout++) = _toebcdic[
  +	    (unsigned char) (pr2six[_toascii[*bufin]] << 2 | pr2six[_toascii[bufin[1]]] >> 4)];
  +	*(bufout++) = _toebcdic[
  +	    (unsigned char) (pr2six[_toascii[bufin[1]]] << 4 | pr2six[_toascii[bufin[2]]] >> 2)];
  +	*(bufout++) = _toebcdic[
  +	    (unsigned char) (pr2six[_toascii[bufin[2]]] << 6 | pr2six[_toascii[bufin[3]]])];
  +	bufin += 4;
  +	nprbytes -= 4;
  +    }
  +
  +    if (nprbytes & 03) {
  +	if (pr2six[_toascii[bufin[-2]]] > 63)
  +	    nbytesdecoded -= 2;
  +	else
  +	    nbytesdecoded -= 1;
  +    }
  +    bufplain[nbytesdecoded] = '\0';
  +#endif /*CHARSET_EBCDIC*/
       return bufplain;
   }
   
  
  
  
  1.63      +23 -6     apachen/src/modules/standard/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/modules/standard/mod_include.c,v
  retrieving revision 1.62
  retrieving revision 1.63
  diff -u -u -r1.62 -r1.63
  --- mod_include.c	1998/01/08 03:16:48	1.62
  +++ mod_include.c	1998/01/13 23:11:19	1.63
  @@ -95,7 +95,11 @@
   #define DEFAULT_TIME_FORMAT "%A, %d-%b-%Y %H:%M:%S %Z"
   #define SIZEFMT_BYTES 0
   #define SIZEFMT_KMG 1
  -
  +#ifdef CHARSET_EBCDIC
  +#define RAW_ASCII_CHAR(ch)  _toebcdic[(unsigned char)ch]
  +#else /*CHARSET_EBCDIC*/
  +#define RAW_ASCII_CHAR(ch)  (ch)
  +#endif /*CHARSET_EBCDIC*/
   
   /* ------------------------ Environment function -------------------------- */
   
  @@ -165,11 +169,20 @@
    * errors is and little can really be done to help the error in 
    * any case.
    */
  +#ifndef CHARSET_EBCDIC
  +#define FLUSH_BUF(r) \
  + { \
  +   rwrite(outbuf, outind, r); \
  +   outind = 0; \
  + }
  +#else /*CHARSET_EBCDIC*/
   #define FLUSH_BUF(r) \
    { \
  +   ebcdic2ascii(outbuf, outbuf, outind); \
      rwrite(outbuf, outind, r); \
      outind = 0; \
    }
  +#endif /*CHARSET_EBCDIC*/
   
   /*
    * f: file handle being read from
  @@ -306,18 +319,18 @@
                   p--;            /* no data to output */
               }
               else {
  -                *p = val;
  +                *p = RAW_ASCII_CHAR(val);
               }
           }
           else {
               j = i - 1;
  -            if (i - 1 > MAXENTLEN || entlist[i - 1] == NULL) {
  +            if (j > MAXENTLEN || entlist[j] == NULL) {
                   /* wrong length */
                   *p = '&';
                   continue;       /* skip it */
               }
  -            for (ents = entlist[i - 1]; *ents != '\0'; ents += i) {
  -                if (strncmp(s + 1, ents, i - 1) == 0) {
  +            for (ents = entlist[j]; *ents != '\0'; ents += i) {
  +                if (strncmp(s + 1, ents, j) == 0) {
                       break;
                   }
               }
  @@ -326,7 +339,7 @@
                   *p = '&';       /* unknown */
               }
               else {
  -                *p = ((const unsigned char *) ents)[i - 1];
  +                *p = RAW_ASCII_CHAR(((const unsigned char *) ents)[j]);
                   s += i;
               }
           }
  @@ -793,7 +806,11 @@
           return -1;
       }
   
  +#ifndef CHARSET_EBCDIC
       send_fd(f, r);
  +#else /*CHARSET_EBCDIC*/
  +    send_fd_length_cnv(f, r, -1, 1);
  +#endif /*CHARSET_EBCDIC*/
       pfclose(r->pool, f);        /* will wait for zombie when
                                    * r->pool is cleared
                                    */
  
  
  
  1.29      +7 -2      apachen/src/modules/standard/mod_mime.c
  
  Index: mod_mime.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/modules/standard/mod_mime.c,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -u -r1.28 -r1.29
  --- mod_mime.c	1998/01/07 16:46:53	1.28
  +++ mod_mime.c	1998/01/13 23:11:23	1.29
  @@ -183,8 +183,13 @@
    * get private versions through AddType...
    */
   
  -#define MIME_HASHSIZE 27
  -#define hash(i) (isalpha(i) ? (tolower(i)) - 'a' : 26)
  +/* 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) (isalpha(i) ? (tolower(i)) - 'a' : (MIME_HASHSIZE-1))
   
   static table *hash_buckets[MIME_HASHSIZE];
   
  
  
  
  1.61      +6 -1      apachen/src/modules/standard/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /home/cvs/apachen/src/modules/standard/mod_rewrite.c,v
  retrieving revision 1.60
  retrieving revision 1.61
  diff -u -u -r1.60 -r1.61
  --- mod_rewrite.c	1998/01/13 22:21:07	1.60
  +++ mod_rewrite.c	1998/01/13 23:11:26	1.61
  @@ -2266,9 +2266,14 @@
       if (uri != NULL && strlen(uri) > 2 && uri[0] == '/' && uri[1] == '~') {
           /* cut out the username */
           for (j = 0, i = 2; j < sizeof(user)-1 && uri[i] != '\0' && 
  +#ifndef CHARSET_EBCDIC
                          (   (uri[i] >= '0' && uri[i] <= '9')
                           || (uri[i] >= 'a' && uri[i] <= 'z')
  -                        || (uri[i] >= 'A' && uri[i] <= 'Z')); )
  +                        || (uri[i] >= 'A' && uri[i] <= 'Z'))
  +#else
  +                       isalnum(uri[i])
  +#endif
  +                        ; )
               user[j++] = uri[i++];
           user[j] = '\0';
   
  
  
  
  1.1                  apachen/src/os/bs2000/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  Makefile
  
  
  
  1.1                  apachen/src/os/bs2000/Makefile.tmpl
  
  Index: Makefile.tmpl
  ===================================================================
  CFLAGS=$(OPTIM) $(CFLAGS1) $(EXTRA_CFLAGS)
  LIBS=$(EXTRA_LIBS) $(LIBS1)
  INCLUDES=$(INCLUDES1) $(INCLUDES_DEPTH2) $(EXTRA_INCLUDES)
  LFLAGS=$(LFLAGS1) $(EXTRA_LFLAGS)
  INCDIR=../../main
  
  OBJS=   os.o os-inline.o ebcdic.o
  
  LIB=	libos.a
  
  all:	$(LIB)
  
  $(LIB): $(OBJS)
  	rm -f $@
  	ar cr $@ $(OBJS)
  	$(RANLIB) $@
  
  .c.o:
  	$(CC) -c $(INCLUDES) $(CFLAGS) $(SPACER) $<
  
  clean:
  	rm -f $(OBJS) $(LIB)
  
  $(OBJS): Makefile
  os.o:	os.c os-inline.c
  ebcdic.o: ebcdic.c
  # DO NOT REMOVE
  os.o:	os.c
  
  
  
  1.1                  apachen/src/os/bs2000/ebcdic.c
  
  Index: ebcdic.c
  ===================================================================
  #ifdef CHARSET_EBCDIC
  #include "ebcdic.h"
  /*
  	   Initial Port for  pache-1.3 by <Ma...@Mch.SNI.De>
  
  "BS2000 OSD" is a POSIX on a main frame.
  It is made by Siemens Nixdorf AG, Germany.
  Within the POSIX subsystem, the same character set was chosen as in
  "native BS2000", namely EBCDIC.  Yes, tcsh now runs on EBCDIC platforms, too.
  
  EBCDIC Table. (Yes, in EBCDIC, the letters 'a'..'z' are not contiguous!)
  This table is bijective, i.e. there are no ambigous or duplicate characters
  00    00 01 02 03 85 09 86 7f  87 8d 8e 0b 0c 0d 0e 0f  *................*
  10    10 11 12 13 8f 0a 08 97  18 19 9c 9d 1c 1d 1e 1f  *................*
  20    80 81 82 83 84 92 17 1b  88 89 8a 8b 8c 05 06 07  *................*
  30    90 91 16 93 94 95 96 04  98 99 9a 9b 14 15 9e 1a  *................*
  40    20 a0 e2 e4 e0 e1 e3 e5  e7 f1 60 2e 3c 28 2b 7c  * .........`.<(+|*
  50    26 e9 ea eb e8 ed ee ef  ec df 21 24 2a 29 3b 9f  *&.........!$*);.*
  60    2d 2f c2 c4 c0 c1 c3 c5  c7 d1 5e 2c 25 5f 3e 3f  *-/........^,%_>?*
  70    f8 c9 ca cb c8 cd ce cf  cc a8 3a 23 40 27 3d 22  *..........:#@'="*
  80    d8 61 62 63 64 65 66 67  68 69 ab bb f0 fd fe b1  *.abcdefghi......*
  90    b0 6a 6b 6c 6d 6e 6f 70  71 72 aa ba e6 b8 c6 a4  *.jklmnopqr......*
  a0    b5 af 73 74 75 76 77 78  79 7a a1 bf d0 dd de ae  *..stuvwxyz......*
  b0    a2 a3 a5 b7 a9 a7 b6 bc  bd be ac 5b 5c 5d b4 d7  *...........[\]..*
  c0    f9 41 42 43 44 45 46 47  48 49 ad f4 f6 f2 f3 f5  *.ABCDEFGHI......*
  d0    a6 4a 4b 4c 4d 4e 4f 50  51 52 b9 fb fc db fa ff  *.JKLMNOPQR......*
  e0    d9 f7 53 54 55 56 57 58  59 5a b2 d4 d6 d2 d3 d5  *..STUVWXYZ......*
  f0    30 31 32 33 34 35 36 37  38 39 b3 7b dc 7d da 7e  *0123456789.{.}.~*
  */
  unsigned char _toascii[256] = {
  /*00*/ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
         0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /*................*/
  /*10*/ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,
         0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /*................*/
  /*20*/ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,
         0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /*................*/
  /*30*/ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
         0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /*................*/
  /*40*/ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
         0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+|*/
  /*50*/ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
         0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /*&.........!$*);.*/
  /*60*/ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
         0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/
  /*70*/ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
         0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /*..........:#@'="*/
  /*80*/ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
         0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /*.abcdefghi......*/
  /*90*/ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
         0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /*.jklmnopqr......*/
  /*a0*/ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
         0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /*..stuvwxyz......*/
  /*b0*/ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
         0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /*...........[\]..*/
  /*c0*/ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
         0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /*.ABCDEFGHI......*/
  /*d0*/ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
         0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /*.JKLMNOPQR......*/
  /*e0*/ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
         0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /*..STUVWXYZ......*/
  /*f0*/ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  	    0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e  /*0123456789.{.}.~*/
  };
  /* The same, for ascii-in-ebcdic
  00    00 01 02 03 37 2d 2e 2f  16 05 15 0b 0c 0d 0e 0f  *................*
  10    10 11 12 13 3c 3d 32 26  18 19 3f 27 1c 1d 1e 1f  *................*
  20    40 5a 7f 7b 5b 6c 50 7d  4d 5d 5c 4e 6b 60 4b 61  * !"#$%&'()*+,-./*
  30    f0 f1 f2 f3 f4 f5 f6 f7  f8 f9 7a 5e 4c 7e 6e 6f  *0123456789:;<=>?*
  40    7c c1 c2 c3 c4 c5 c6 c7  c8 c9 d1 d2 d3 d4 d5 d6  *@ABCDEFGHIJKLMNO*
  50    d7 d8 d9 e2 e3 e4 e5 e6  e7 e8 e9 bb bc bd 6a 6d  *PQRSTUVWXYZ[\]^_*
  60    4a 81 82 83 84 85 86 87  88 89 91 92 93 94 95 96  *`abcdefghijklmno*
  70    97 98 99 a2 a3 a4 a5 a6  a7 a8 a9 fb 4f fd ff 07  *pqrstuvwxyz{|}~.*
  80    20 21 22 23 24 04 06 08  28 29 2a 2b 2c 09 0a 14  *................*
  90    30 31 25 33 34 35 36 17  38 39 3a 3b 1a 1b 3e 5f  *................*
  a0    41 aa b0 b1 9f b2 d0 b5  79 b4 9a 8a ba ca af a1  *................*
  b0    90 8f ea fa be a0 b6 b3  9d da 9b 8b b7 b8 b9 ab  *................*
  c0    64 65 62 66 63 67 9e 68  74 71 72 73 78 75 76 77  *................*
  d0    ac 69 ed ee eb ef ec bf  80 e0 fe dd fc ad ae 59  *................*
  e0    44 45 42 46 43 47 9c 48  54 51 52 53 58 55 56 57  *................*
  f0    8c 49 cd ce cb cf cc e1  70 c0 de db dc 8d 8e df  *................*
  */
  unsigned char _toebcdic[256] = {
  /*00*/  0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
  	0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,  /*................*/
  /*10*/  0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
  	0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,  /*................*/
  /*20*/  0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
  	0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,  /* !"#$%&'()*+,-./*/
  /*30*/  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  	0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,  /*0123456789:;<=>?*/
  /*40*/  0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  	0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,  /*@ABCDEFGHIJKLMNO*/
  /*50*/  0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
  	0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d,  /*PQRSTUVWXYZ[\]^_*/
  /*60*/  0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  	0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,  /*`abcdefghijklmno*/
  /*70*/  0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
  	0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07,  /*pqrstuvwxyz{|}~.*/
  /*80*/  0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08,
  	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14,  /*................*/
  /*90*/  0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17,
  	0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f,  /*................*/
  /*a0*/  0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5,
  	0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1,  /*................*/
  /*b0*/  0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
  	0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,  /*................*/
  /*c0*/  0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
  	0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,  /*................*/
  /*d0*/  0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
  	0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59,  /*................*/
  /*e0*/  0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
  	0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,  /*................*/
  /*f0*/  0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
  	0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf   /*................*/
  };
  
  /* Translate a memory block from EBCDIC (host charset) to ASCII (net charset)
   * dest and srce may be identical, or separate memory blocks, but
   * should not overlap.
   */
  void
  ebcdic2ascii(unsigned char *dest, const unsigned char *srce, size_t count)
  {
  	while (count-- != 0) {
  		*dest++ = (*srce == '\015' || *srce=='\012') 
  			? *srce : _toascii[*srce];
  		++srce;
  	}
  }
  void
  ascii2ebcdic(unsigned char *dest, const unsigned char *srce, size_t count)
  {
  	while (count-- != 0) {
  		*dest++ = _toebcdic[*srce++];
  	}
  }
  #endif /*CHARSET_EBCDIC*/
  
  
  
  1.1                  apachen/src/os/bs2000/ebcdic.h
  
  Index: ebcdic.h
  ===================================================================
  #include <sys/types.h>
  
  extern const char _toascii[256];
  extern const char _toebcdic[256];
  void ebcdic2ascii(unsigned char *dest, const unsigned char *srce, size_t count);
  void ascii2ebcdic(unsigned char *dest, const unsigned char *srce, size_t count);
  
  
  
  
  1.1                  apachen/src/os/bs2000/os-inline.c
  
  Index: os-inline.c
  ===================================================================
  /*
   * This file contains functions which can be inlined if the compiler
   * has an "inline" modifier. Because of this, this file is both a
   * header file and a compilable module.
   *
   * Only inlineable functions should be defined in here. They must all
   * include the INLINE modifier. 
   *
   * If the compiler supports inline, this file will be #included as a
   * header file from os.h to create all the inline function
   * definitions. INLINE will be defined to whatever is required on
   * function definitions to make them inline declarations.
   *
   * If the compiler does not support inline, this file will be compiled
   * as a normal C file into libos.a (along with os.c). In this case
   * INLINE will _not_ be set so we can use this to test if we are
   * compiling this source file.  
   */
  
  #ifndef INLINE
  #define INLINE
  
  /* Anything required only when compiling */
  
  #endif
  
  INLINE int os_is_path_absolute(char *file)
  {
    return (file && file[0] == '/' ? 1 : 0);
  }
  
  
  
  1.1                  apachen/src/os/bs2000/os.c
  
  Index: os.c
  ===================================================================
  /*
   * This file will include OS specific functions which are not inlineable.
   * Any inlineable functions should be defined in os-inline.c instead.
   */
  
  #include "os.h"
  
  
  
  1.1                  apachen/src/os/bs2000/os.h
  
  Index: os.h
  ===================================================================
  /*
   * This file in included in all Apache source code. It contains definitions
   * of facilities available on _this_ operating system (HAVE_* macros),
   * and prototypes of OS specific functions defined in os.c or os-inline.c
   */
  
  #if !defined(INLINE) && defined(USE_GNU_INLINE)
  /* Compiler supports inline, so include the inlineable functions as
   * part of the header
   */
  #define INLINE extern ap_inline
  #include "os-inline.c"
  #endif
  
  #ifndef INLINE
  /* Compiler does not support inline, so prototype the inlineable functions
   * as normal
   */
  extern int os_is_path_absolute(char *f);
  #endif