martin 98/01/26 08:46:20
Modified: . STATUS
src README.EBCDIC
src/main buff.c buff.h http_bprintf.c http_core.c
http_protocol.c
src/modules/standard mod_cgi.c mod_include.c
src/os/bs2000 ebcdic.c os.c os.h
Log:
Fix CGI-Execution for EBCDIC hosts.
Revision Changes Path
1.129 +1 -0 apachen/STATUS
Index: STATUS
===================================================================
RCS file: /home/cvs/apachen/STATUS,v
retrieving revision 1.128
retrieving revision 1.129
diff -u -u -r1.128 -r1.129
--- STATUS 1998/01/25 18:41:51 1.128
+++ STATUS 1998/01/26 16:46:05 1.129
@@ -134,6 +134,7 @@
(enable with #define NEED_HASHBANG_EMUL)
* more mod_mime_magic cleanup
* Add more compile time diagnosis to main's -V switch
+ * [Port] Fix CGI-Execution for EBCDIC hosts.
Available Patches:
1.2 +11 -7 apachen/src/README.EBCDIC
Index: README.EBCDIC
===================================================================
RCS file: /home/cvs/apachen/src/README.EBCDIC,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -u -r1.1 -r1.2
--- README.EBCDIC 1998/01/13 23:11:04 1.1
+++ README.EBCDIC 1998/01/26 16:46:06 1.2
@@ -58,17 +58,22 @@
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.
+ configuring a MIME type "text/x-ascii-XXXX" for it using AddType.
* 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.
+ file types. This of course requires the user to copy them to the
+ mainframe host using the "rcp -b" binary switch.
* Server parsed files are always assumed to be in native (i.e.,
EBCDIC) format as used on the machine, and are converted after
processing.
-*
+* For CGI output, the CGI script determines whether a conversion is
+ needed or not: by setting the appropriate Content-Type, text files
+ can be converted, or GIF output can be passed through unmodified.
+ An example for the latter case is the wwwcount program which we ported
+ as well.
What works:
- In the following list,
@@ -87,7 +92,7 @@
mod_auth_dbm.c - / no libdbm
mod_autoindex.c +
mod_cern_meta.c ?
- mod_cgi.c - / exec of scripts via #! doesn't work
+ mod_cgi.c +
mod_digest.c - / MD5 not ported yet
mod_dir.c +
mod_dld.c - / no shared libs
@@ -96,7 +101,7 @@
mod_expires.c +
mod_headers.c +
mod_imap.c +
- mod_include.c + / only <!--#exec cgi= doesn't work (see mod_cgi).
+ mod_include.c +
mod_info.c + / some flaws
mod_log_agent.c +
mod_log_config.c +
@@ -118,6 +123,5 @@
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
+ Martin Kraemer, 25-Jan-1998
1.59 +63 -60 apachen/src/main/buff.c
Index: buff.c
===================================================================
RCS file: /home/cvs/apachen/src/main/buff.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -u -r1.58 -r1.59
--- buff.c 1998/01/22 21:00:06 1.58
+++ buff.c 1998/01/26 16:46:07 1.59
@@ -283,6 +283,10 @@
else
fb->outbase = NULL;
+#ifdef CHARSET_EBCDIC
+ fb->flags |= (flags & B_SOCKET) ? (B_EBCDIC2ASCII | B_ASCII2EBCDIC) : 0;
+#endif /*CHARSET_EBCDIC*/
+
fb->inptr = fb->inbase;
fb->incnt = 0;
@@ -370,7 +374,12 @@
bflush(fb);
}
/* assume there's enough space now */
+#ifdef CHARSET_EBCDIC
+ /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII
*/
+ ebcdic2ascii(&fb->outbase[fb->outcnt], chunksize, chunk_header_size);
+#else /*CHARSET_EBCDIC*/
memcpy(&fb->outbase[fb->outcnt], chunksize, chunk_header_size);
+#endif /*CHARSET_EBCDIC*/
fb->outchunk = fb->outcnt;
fb->outcnt += chunk_header_size;
fb->outchunk_header_size = chunk_header_size;
@@ -417,6 +426,7 @@
fb->outbase[i - 1] = '\015';
}
#ifdef CHARSET_EBCDIC
+ /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII
*/
ebcdic2ascii(&fb->outbase[fb->outchunk], &fb->outbase[fb->outchunk],
fb->outchunk_header_size);
#endif /*CHARSET_EBCDIC*/
@@ -598,6 +608,11 @@
* buffer from before we went unbuffered. */
if (fb->incnt) {
i = (fb->incnt > nbyte) ? nbyte : fb->incnt;
+#ifdef CHARSET_EBCDIC
+ if (fb->flags & B_ASCII2EBCDIC)
+ ascii2ebcdic(buf, fb->inptr, i);
+ else
+#endif /*CHARSET_EBCDIC*/
memcpy(buf, fb->inptr, i);
fb->incnt -= i;
fb->inptr += i;
@@ -610,6 +625,11 @@
nrd = fb->incnt;
/* can we fill the buffer */
if (nrd >= nbyte) {
+#ifdef CHARSET_EBCDIC
+ if (fb->flags & B_ASCII2EBCDIC)
+ ascii2ebcdic(buf, fb->inptr, nbyte);
+ else
+#endif /*CHARSET_EBCDIC*/
memcpy(buf, fb->inptr, nbyte);
fb->incnt = nrd - nbyte;
fb->inptr += nbyte;
@@ -617,6 +637,11 @@
}
if (nrd > 0) {
+#ifdef CHARSET_EBCDIC
+ if (fb->flags & B_ASCII2EBCDIC)
+ ascii2ebcdic(buf, fb->inptr, nrd);
+ else
+#endif /*CHARSET_EBCDIC*/
memcpy(buf, fb->inptr, nrd);
nbyte -= nrd;
buf = nrd + (char *) buf;
@@ -629,6 +654,10 @@
if (nbyte >= fb->bufsiz) {
/* read directly into buffer */
i = read_with_errors(fb, buf, nbyte);
+#ifdef CHARSET_EBCDIC
+ if (i > 0 && bgetflag(fb, B_ASCII2EBCDIC))
+ ascii2ebcdic(buf, buf, nbyte);
+#endif /*CHARSET_EBCDIC*/
if (i == -1) {
return nrd ? nrd : -1;
}
@@ -643,6 +672,11 @@
fb->incnt = i;
if (i > nbyte)
i = nbyte;
+#ifdef CHARSET_EBCDIC
+ if (fb->flags & B_ASCII2EBCDIC)
+ ascii2ebcdic(buf, fb->inptr, i);
+ else
+#endif /*CHARSET_EBCDIC*/
memcpy(buf, fb->inptr, i);
fb->incnt -= i;
fb->inptr += i;
@@ -702,8 +736,8 @@
continue; /* restart with the new data */
}
-#ifndef CHARSET_EBCDIC
ch = fb->inptr[i++];
+#ifndef CHARSET_EBCDIC
if (ch == '\012') { /* got LF */
if (ct == 0)
buff[ct++] = '\n';
@@ -716,15 +750,9 @@
i--; /* no room for LF */
break;
}
- if (ct == n - 1) {
- i--; /* push back ch */
- break;
- }
-
- buff[ct++] = ch;
- }
#else /* an EBCDIC machine: do the same, but convert to EBCDIC on the fly: */
- ch = os_toebcdic[(unsigned char)fb->inptr[i++]];
+ if (fb->flags & B_ASCII2EBCDIC)
+ ch = os_toebcdic[(unsigned char)ch];
if (ch == os_toebcdic['\012']) { /* got LF */
if (ct == 0)
buff[ct++] = '\n';
@@ -737,6 +765,7 @@
i--; /* no room for LF */
break;
}
+#endif
if (ct == n - 1) {
i--; /* push back ch */
break;
@@ -744,7 +773,6 @@
buff[ct++] = ch;
}
-#endif
fb->incnt -= i;
fb->inptr += i;
@@ -787,7 +815,9 @@
#ifndef CHARSET_EBCDIC
*buff = fb->inptr[0];
#else /*CHARSET_EBCDIC*/
- *buff = os_toebcdic[(unsigned char)fb->inptr[0]];
+ *buff = (fb->flags & B_ASCII2EBCDIC)
+ ? os_toebcdic[(unsigned char)fb->inptr[0]]
+ : fb->inptr[0];
#endif /*CHARSET_EBCDIC*/
return 1;
}
@@ -837,11 +867,7 @@
char ss[1];
int rc;
-#ifndef CHARSET_EBCDIC
ss[0] = c;
-#else
- ss[0] = os_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
@@ -865,11 +891,7 @@
if (i != 1)
return EOF;
else
-#ifndef CHARSET_EBCDIC
return buf[0];
-#else /*CHARSET_EBCDIC*/
- return os_toebcdic[(unsigned char)buf[0]];
-#endif /*CHARSET_EBCDIC*/
}
@@ -1007,6 +1029,10 @@
/* without writev() this has poor performance, too bad */
ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012", nbyte);
+#ifdef CHARSET_EBCDIC
+ /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII
*/
+ ebcdic2ascii(chunksize, chunksize, strlen(chunksize));
+#endif /*CHARSET_EBCDIC*/
if (write_it_all(fb, chunksize, strlen(chunksize)) == -1)
return -1;
if (write_it_all(fb, buf, nbyte) == -1)
@@ -1019,6 +1045,7 @@
vec[0].iov_len = ap_snprintf(chunksize, sizeof(chunksize), "%x\015\012",
nbyte);
#ifdef CHARSET_EBCDIC
+ /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII
*/
ebcdic2ascii(chunksize, chunksize, strlen(chunksize));
#endif /*CHARSET_EBCDIC*/
vec[1].iov_base = (void *) buf; /* cast is to avoid const warning */
@@ -1058,6 +1085,7 @@
vec[nvec].iov_len = ap_snprintf(chunksize, sizeof(chunksize),
"%x\015\012", nbyte);
#ifdef CHARSET_EBCDIC
+ /* Chunks are an HTTP/1.1 Protocol feature. They must ALWAYS be in ASCII
*/
ebcdic2ascii(chunksize, chunksize, strlen(chunksize));
#endif /*CHARSET_EBCDIC*/
++nvec;
@@ -1090,6 +1118,22 @@
API_EXPORT(int) bwrite(BUFF *fb, const void *buf, int nbyte)
{
int i, nwr;
+#ifdef CHARSET_EBCDIC
+ static char *cbuf = NULL;
+ static int csize = 0;
+
+ if (bgetflag(fb, B_EBCDIC2ASCII)) {
+ if (nbyte > csize) {
+ if (cbuf != NULL)
+ free(cbuf);
+ cbuf = malloc(csize = nbyte+HUGE_STRING_LEN);
+ if (cbuf == NULL)
+ csize = 0;
+ }
+ ebcdic2ascii((cbuf) ? cbuf : (void*)buf, buf, nbyte);
+ buf = (cbuf) ? cbuf : buf;
+ }
+#endif /*CHARSET_EBCDIC*/
if (fb->flags & (B_WRERR | B_EOUT))
return -1;
@@ -1298,54 +1342,17 @@
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 = os_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*/
}
/*
@@ -1363,11 +1370,7 @@
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.33 +8 -5 apachen/src/main/buff.h
Index: buff.h
===================================================================
RCS file: /home/cvs/apachen/src/main/buff.h,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -u -r1.32 -r1.33
--- buff.h 1998/01/21 19:17:35 1.32
+++ buff.h 1998/01/26 16:46:08 1.33
@@ -83,6 +83,10 @@
#define B_SAFEREAD (128)
/* buffer is a socket */
#define B_SOCKET (256)
+#ifdef CHARSET_EBCDIC
+#define B_ASCII2EBCDIC 0x40000000 /* Enable conversion for this buffer */
+#define B_EBCDIC2ASCII 0x80000000 /* Enable conversion for this buffer */
+#endif /*CHARSET_EBCDIC*/
typedef struct buff_struct BUFF;
@@ -149,9 +153,6 @@
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,...)
@@ -174,11 +175,13 @@
#else /*CHARSET_EBCDIC*/
#define bgetc(fb) ( ((fb)->incnt == 0) ? bfilbuf(fb) : \
- ((fb)->incnt--, os_toebcdic[(unsigned
char)*((fb)->inptr++)]) )
+ ((fb)->incnt--, (fb->flags & B_ASCII2EBCDIC)\
+ ?os_toebcdic[(unsigned
char)*((fb)->inptr++)]:*((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++] = os_toascii[(unsigned
char)c], 0))
+ ((fb)->outbase[(fb)->outcnt++] = (fb->flags &
B_EBCDIC2ASCII)\
+ ?os_toascii[(unsigned char)c]:(c), 0))
#endif /*CHARSET_EBCDIC*/
API_EXPORT(int) spawn_child_err_buff(pool *, int (*)(void *), void *,
1.15 +0 -10 apachen/src/main/http_bprintf.c
Index: http_bprintf.c
===================================================================
RCS file: /home/cvs/apachen/src/main/http_bprintf.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -u -r1.14 -r1.15
--- http_bprintf.c 1998/01/13 23:11:08 1.14
+++ http_bprintf.c 1998/01/26 16:46:08 1.15
@@ -95,13 +95,8 @@
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)
@@ -559,13 +554,8 @@
} /* 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.148 +2 -22 apachen/src/main/http_core.c
Index: http_core.c
===================================================================
RCS file: /home/cvs/apachen/src/main/http_core.c,v
retrieving revision 1.147
retrieving revision 1.148
diff -u -u -r1.147 -r1.148
--- http_core.c 1998/01/21 22:15:56 1.147
+++ http_core.c 1998/01/26 16:46:09 1.148
@@ -1823,9 +1823,6 @@
#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.
@@ -1907,35 +1904,18 @@
* 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;
- }
+ os_checkconv(r);
#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.179 +25 -21 apachen/src/main/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/apachen/src/main/http_protocol.c,v
retrieving revision 1.178
retrieving revision 1.179
diff -u -u -r1.178 -r1.179
--- http_protocol.c 1998/01/23 04:11:32 1.178
+++ http_protocol.c 1998/01/26 16:46:10 1.179
@@ -800,6 +800,9 @@
/* Get the request... */
+#ifdef CHARSET_EBCDIC
+ bsetflag(r->connection->client, B_ASCII2EBCDIC|B_EBCDIC2ASCII, 1);
+#endif /* CHARSET_EBCDIC */
keepalive_timeout("read request line", r);
if (!read_request_line(r)) {
kill_timeout(r);
@@ -1059,6 +1062,9 @@
void basic_http_header(request_rec *r)
{
char *protocol;
+#ifdef CHARSET_EBCDIC
+ int convert = bgetflag(r->connection->client, B_EBCDIC2ASCII);
+#endif /*CHARSET_EBCDIC*/
if (r->assbackwards)
return;
@@ -1079,6 +1085,10 @@
else
protocol = SERVER_PROTOCOL;
+#ifdef CHARSET_EBCDIC
+ bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
+#endif /*CHARSET_EBCDIC*/
+
/* Output the HTTP/1.x Status-Line and the Date and Server fields */
bvputs(r->connection->client,
@@ -1089,6 +1099,10 @@
table_unset(r->headers_out, "Date"); /* Avoid bogosity */
table_unset(r->headers_out, "Server");
+#ifdef CHARSET_EBCDIC
+ if (!convert)
+ bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
+#endif /*CHARSET_EBCDIC*/
}
/* Navigator versions 2.x, 3.x and 4.0 betas up to and including 4.0b2
@@ -1207,6 +1221,9 @@
{
int i;
const long int zero = 0L;
+#ifdef CHARSET_EBCDIC
+ int convert = bgetflag(r->connection->client, B_EBCDIC2ASCII);
+#endif /*CHARSET_EBCDIC*/
if (r->assbackwards) {
if (!r->main)
@@ -1228,6 +1245,10 @@
basic_http_header(r);
+#ifdef CHARSET_EBCDIC
+ bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
+#endif /*CHARSET_EBCDIC*/
+
set_keepalive(r);
if (r->chunked) {
@@ -1279,6 +1300,10 @@
/* Set buffer flags for the body */
if (r->chunked)
bsetflag(r->connection->client, B_CHUNK, 1);
+#ifdef CHARSET_EBCDIC
+ if (!convert)
+ bsetflag(r->connection->client, B_EBCDIC2ASCII, convert);
+#endif /*CHARSET_EBCDIC*/
}
/* finalize_request_protocol is called at completion of sending the
@@ -1615,18 +1640,6 @@
}
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;
@@ -1647,11 +1660,6 @@
&& 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;
}
@@ -1903,11 +1911,7 @@
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.68 +11 -0 apachen/src/modules/standard/mod_cgi.c
Index: mod_cgi.c
===================================================================
RCS file: /home/cvs/apachen/src/modules/standard/mod_cgi.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -u -r1.67 -r1.68
--- mod_cgi.c 1998/01/24 19:00:23 1.67
+++ mod_cgi.c 1998/01/26 16:46:14 1.68
@@ -410,6 +410,12 @@
cld.nph = nph;
cld.debug = conf->logname ? 1 : 0;
+#ifdef CHARSET_EBCDIC
+ /* XXX:@@@ Is the generated/included output ALWAYS in text/ebcdic
format? */
+ /* Or must we check the Content-Type first? */
+ bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
+#endif /*CHARSET_EBCDIC*/
+
/*
* we spawn out of r->main if it's there so that we can avoid
* waiting for free_proc_chain to cleanup in the middle of an
@@ -486,6 +492,11 @@
if ((ret = scan_script_header_err_buff(r, script_in, sbuf))) {
return log_script(r, conf, ret, dbuf, sbuf, script_in, script_err);
}
+
+#ifdef CHARSET_EBCDIC
+ /* Now check the Content-Type to decide if conversion is needed */
+ os_checkconv(r);
+#endif /*CHARSET_EBCDIC*/
location = table_get(r->headers_out, "Location");
1.66 +8 -13 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.65
retrieving revision 1.66
diff -u -u -r1.65 -r1.66
--- mod_include.c 1998/01/24 19:00:24 1.65
+++ mod_include.c 1998/01/26 16:46:14 1.66
@@ -169,20 +169,11 @@
* 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
@@ -689,6 +680,9 @@
}
}
+#ifdef CHARSET_EBCDIC
+ bsetflag(rr->connection->client, B_EBCDIC2ASCII, 0);
+#endif
if (!error_fmt && run_sub_req(rr)) {
error_fmt = "unable to include \"%s\" in parsed file %s";
}
@@ -806,11 +800,7 @@
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
*/
@@ -2304,6 +2294,11 @@
add_include_vars(r, DEFAULT_TIME_FORMAT);
}
hard_timeout("send SSI", r);
+
+#ifdef CHARSET_EBCDIC
+ /* XXX:@@@ Is the generated/included output ALWAYS in text/ebcdic
format? */
+ bsetflag(r->connection->client, B_EBCDIC2ASCII, 1);
+#endif
send_parsed_content(f, r);
1.3 +114 -10 apachen/src/os/bs2000/ebcdic.c
Index: ebcdic.c
===================================================================
RCS file: /home/cvs/apachen/src/os/bs2000/ebcdic.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -u -r1.2 -r1.3
--- ebcdic.c 1998/01/16 14:23:33 1.2
+++ ebcdic.c 1998/01/26 16:46:16 1.3
@@ -1,12 +1,66 @@
+/* ====================================================================
+ * Copyright (c) 1998 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. 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/>.
+ *
+ */
+
+
#ifdef CHARSET_EBCDIC
#include "ebcdic.h"
/*
- Initial Port for pache-1.3 by <[EMAIL PROTECTED]>
+ Initial Port for Apache-1.3 by <[EMAIL PROTECTED]>
"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.
+"native BS2000", namely EBCDIC.
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
@@ -27,7 +81,9 @@
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 os_toascii[256] = {
+
+/* The bijective ebcdic-to-ascii table: */
+unsigned char os_toascii_strictly[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,
@@ -59,12 +115,62 @@
/*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.{.}.~*/
+ 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /*0123456789.{.}.~*/
+};
+
+/* This table is (almost) identical to the previous one. The only difference
+ * is the fact that it maps every EBCDIC *except 0x0A* to its ASCII
+ * equivalent. The reason for this table is simple: Throughout the
+ * server, protocol strings are used in the form
+ * "Content-Type: text/plain\015\012". Now all the characters in the string
+ * are stored as EBCDIC, only the semantics of \012 is completely
+ * different from LF (look it up in the table above). \015 happens to be
+ * mapped to \015 anyway, so there's no special case for it.
+ *
+ * In THIS table, EBCDIC-\012 is mapped to ASCII-\012.
+ * This table is therefore used wherever an EBCDIC to ASCII conversion is
+ * needed in the server.
+ */
+/* ebcdic-to-ascii with \012 mapped to ASCII-\n */
+unsigned char os_toascii[256] = {
+/*00*/ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,
+ 0x87, 0x8d, 0x0a, 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
+
+/* The ascii-to-ebcdic table:
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 * !"#$%&'()*+,-./*
+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 [EMAIL PROTECTED]
50 d7 d8 d9 e2 e3 e4 e5 e6 e7 e8 e9 bb bc bd 6a 6d *PQRSTUVWXYZ[\]^_*
@@ -85,7 +191,7 @@
/*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, /* !"#$%&'()*+,-./*/
+ 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,
@@ -122,9 +228,7 @@
ebcdic2ascii(unsigned char *dest, const unsigned char *srce, size_t count)
{
while (count-- != 0) {
- *dest++ = (*srce == '\015' || *srce=='\012')
- ? *srce : os_toascii[*srce];
- ++srce;
+ *dest++ = os_toascii[*srce++];
}
}
void
1.2 +85 -0 apachen/src/os/bs2000/os.c
Index: os.c
===================================================================
RCS file: /home/cvs/apachen/src/os/bs2000/os.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -u -r1.1 -r1.2
--- os.c 1998/01/13 23:11:32 1.1
+++ os.c 1998/01/26 16:46:16 1.2
@@ -1,6 +1,91 @@
+/* ====================================================================
+ * Copyright (c) 1998 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. 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/>.
+ *
+ */
+
/*
* 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"
+
+/* Check the Content-Type to decide if conversion is needed */
+int os_checkconv(struct request_rec *r)
+{
+ int convert_to_ascii;
+
+ /* 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.
+ */
+
+ /* If no content type is set then treat it as (ebcdic) text/plain */
+ convert_to_ascii = (r->content_type == NULL);
+
+ /* Conversion is applied to text/ files only, if ever. */
+ if (r->content_type && strncasecmp(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;
+ }
+ bsetflag(r->connection->client, B_EBCDIC2ASCII, convert_to_ascii);
+
+ return convert_to_ascii;
+}
+
1.2 +10 -0 apachen/src/os/bs2000/os.h
Index: os.h
===================================================================
RCS file: /home/cvs/apachen/src/os/bs2000/os.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -u -r1.1 -r1.2
--- os.h 1998/01/13 23:11:32 1.1
+++ os.h 1998/01/26 16:46:17 1.2
@@ -1,9 +1,13 @@
+#ifndef AP_OS_BS2000_OS_H
+#define AP_OS_BS2000_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
*/
+#include "httpd.h"
+
#if !defined(INLINE) && defined(USE_GNU_INLINE)
/* Compiler supports inline, so include the inlineable functions as
* part of the header
@@ -18,3 +22,9 @@
*/
extern int os_is_path_absolute(char *f);
#endif
+
+/* Sorry if this is ugly, but the include order doesn't allow me
+ * to use request_rec here... */
+struct request_rec;
+extern int os_checkconv(struct request_rec *r);
+#endif /*AP_OS_BS2000_OS_H*/