rtoss

Subversion Repositories:
Compare Path: Rev
With Path: Rev
/ @ 346  →  / @ 347
New file
/httptunnel/HACKING
@@ -0,0 +1,96 @@
General idea.
 
FIXME: client, server. HTTP.
 
All HTTP requests are made by the client, htc, and are served by the
server, hts.
 
Data is sent to the server using HTTP PUT requests. These have a
Content-Length header line, which is obeyed strictly if the --strict
option is used. tunnel.c provides a nice interface to the
complexities of HTTP requests. See tunnel.h for information about the
programming interface.
 
In the other direction, data is transferred using HTTP GET requests.
 
 
Proxy buffering.
 
Some proxies buffer data in HTTP PUT or POST requests. FIXME: explain
why this is a problem and how it is solved.
 
 
Debugging.
 
To enable debugging code, use --enable-debug with 'configure'. This
will make htc and hts recognize a --debug switch.
--debug 0 - no messages whatsoever
--debug 1 - log_notice () - important events
--debug 2 - log_error () - unexpected errors
--debug 3 - log_debug () - sparse debugging
--debug 4 - log_verbose () - debugging in innner loops
--debug 5 - log_annoying () - system calls and more
 
Without --enable-debug, log_notice() and log_error() will log using
syslog() with level LOG_NOTICE and LOG_ERROR, respectively.
log_debug(), log_verbose(), and log_annoying() will be disabled.
 
 
Some notes about the protocol.
 
The data sent in HTTP requests is in itself formatted according to a
simple protocol. This is needed becase some HTTP proxy servers buffer
data before sending it to its final destination.
 
There are seven different requests in this protocol, and there are
two types of requests. Requests with the 0x40 bit set consists of
just one byte, with no additional data. Requests with the 0x40 bit
clear have a two-byte length field and a variable length data field.
 
TUNNEL_OPEN
01 xx xx yy...
xx xx = length of auth data
yy... = auth data
 
OPEN is the initial request. For now, auth data is unused,
but should be used for authentication.
 
TUNNEL_DATA
02 xx xx yy...
xx xx = lenth of data
yy... = data
 
DATA is the one and only way to send data.
 
TUNNEL_PADDING
03 xx xx yy...
xx xx = lenth of padding
yy... = padding (will be discarded)
 
PADDING exists only to allow padding the HTTP data. This is
needed for HTTP proxies that buffer data.
 
TUNNEL_ERROR
04 xx xx yy...
xx xx = length of error message
yy... = error message
 
Report an error to the peer.
 
TUNNEL_PAD1
45
PAD1 can be used for padding when a PADDING request would be
too long with regard to Content-Length. PADDING should always
be preferred, though, because it's easier for the recipent to
parse one large request than many small.
 
TUNNEL_CLOSE
46
CLOSE is used to close the tunnel. No more data can be sent
after this request is issued, except for a TUNNEL_DISCONNECT.
 
TUNNEL_DISCONNECT
47
DISCONNECT is used to close the connection temporarily,
probably because Content-Length - 1 number of bytes of data
has been sent in the HTTP request.
New file
/httptunnel/base64.c
@@ -0,0 +1,93 @@
/*
base64.c
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#include <string.h>
#include <stdlib.h>
 
#include "config.h"
#include "base64.h"
#include "common.h"
 
static int encode[] =
{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'
};
 
/*
Base64-encode LENGTH bytes of DATA in *CODE, which will be a newly
malloced area. *CODE will be a null-terminated string.
 
Return -1 on failure, or number of bytes of base64 code on success.
*/
 
ssize_t
encode_base64 (const void *data, size_t length, char **code)
{
const unsigned char *s, *end;
unsigned char *buf;
unsigned int x;
ssize_t n;
int i, j;
 
if (length == 0)
return 0;
 
end = (char *)data + length - 3;
 
buf = malloc (4 * ((length + 2) / 3) + 1);
if (buf == NULL)
return -1;
 
n = 0;
 
for (s = data; s < end;)
{
x = *s++ << 24;
x |= *s++ << 16;
x |= *s++ << 8;
 
*buf++ = encode[x >> 26];
x <<= 6;
*buf++ = encode[x >> 26];
x <<= 6;
*buf++ = encode[x >> 26];
x <<= 6;
*buf++ = encode[x >> 26];
n += 4;
}
 
end += 3;
 
x = 0;
for (i = 0; s < end; i++)
x |= *s++ << (24 - 8 * i);
 
for (j = 0; j < 4; j++)
{
if (8 * i >= 6 * j)
{
*buf++ = encode [x >> 26];
x <<= 6;
n++;
}
else
{
*buf++ = '=';
n++;
}
}
 
*buf = 0;
 
*code = buf - n;
return n;
}
New file
/httptunnel/TODO
@@ -0,0 +1,154 @@
Things to do, in a slightly random order:
 
* Error detection.
 
Maybe HTTP over TCP isn't all that reliable? Especially
considering that there's a proxy in the middle.
 
Detect lost connections and reconnect. Checksum data. Retransmit
lost data. Etc etc.
 
This is a big project, but it would be nice to have a reliable
transport layer (I THINK it's called "transport layer").
 
>> Actually, it seems reliable enough.
 
* Actually use the #defines in config.h
 
What good is autoconf if you don't use what it generates for you?
 
>> Getting better.
 
* Handling of TUNNEL_OPEN in the server.
 
Come up with something useful to put in the auth_data section
of a TUNNEL_OPEN request.
 
* Adhere to Content-Length, even when doing a tunnel_close().
 
For now, Content-Length is adhered to strictly everywhere except
in tunnel_close(). tunnel_close() could, optionally, send
padding after the close request.
 
>> Done, but it's not optional. Yet. Should it be?
 
* Auto-detect proxy PUT/POST buffering.
 
Idea: make a second HTTP GET request that will be used to send
ACKs to the client when HTTP PUT/POST data arrives. If data is
sent in a PUT/POST reqest and the ACK channel is silent, pad the
PUT/POST data until ACK arrives.
 
* Remove busy poll loops.
 
I wrote then that way only because I wanted fast results.
I didn't intend them to be that way forever. I promise!
 
Instead, use select() or poll() with nice timeouts.
 
>> Done for the server. Remaining: don't use blocking
read()s, buffer data until a complete request is received.
 
>> Done for the client.
 
* Make client and server not fork?
 
>> Done for the server.
 
>> Done for the client.
 
* Multiplex data channels in the tunnel.
 
>> Perhaps in external programs.
>> See Port forwarding.
 
* Socket-to-device and device-to-socket gateways.
 
>> External programs.
>> See Port forwarding.
 
* CGI-to-hts gateway.
 
If the HTTP tunnel is to connect to an already existing HTTP
server, there could be a CGI program relaying tunnel traffic
to hts.
 
* tunnel_write () always tries to write all the data, regardless of
wheter O_NONLBOCK is set or not.
 
Is this a problem?
 
* Use zlib for compression.
 
Note that padding can't be compressed.
 
* Port forwarding.
 
'htf --port 23 --destination my.site.org:23' waits for a connection
on local port 23, and talks to htfmux using a small protocol.
 
htfmux waits for connections and talks to htc trough a pseudo-tty.
 
htfmux reads data from all its connections and multiplexes it over
the tunnel. Yet another protocol for this.
 
In the other end, hts talks to htdemux, which handles the other half
of port forwarding.
 
Why separate htf and hftmux? Because there is only one instance
of hftmux running. To add or remove a new port forwarding, just
run a new htf or kill an already running one. This could also
be accomplished with hftmux re-reading a configuration file
every time it gets a SIGHUP.
 
Either way is possible. Implement one and see if someone hacks
up something better.
 
* Use 'Connection: keep-alive'.
 
Keep the connection alive instead of closing it down efter every
HTTP request.
 
* Threading.
 
Separate thread for device/port input and tunnel input.
 
* --paranoid switch.
 
Make the data look like HTML code!
 
* protocol abstraction
 
From: Raphael Manfredi <Raphael.Manfredi@st.com>
Date: Tue, 17 Aug 1999 16:36:43 +0200
 
Rename httptunnel as "xtptunnel" :-)
 
Why limit yourself to http? Why not also allow ftptunnel?
 
xts -t ftp .... <=> xtc -t ftp ....
xtc -t http ... <=> xtc -t http ....
 
If the "tunnel_*" routines are made "generic" in their signature, one could
imagine to put them all in a stucture:
 
struct xtp {
/* open routine pointer */
/* read routine pointer */
/* write routine pointer */
/* close routine pointer */
} xtp;
 
Then one would get one xtp "driving" structure per protocol type. The
code would get much more modular, and extensible, and common code could
get factored out, leaving only protocol-specific idiosyncracies in the
driving routines.
 
This kind of design looks like a filesystem stack: on top of it, VFS, a
virtual file system, and underneath, specific "drivers" for low-level
routines for UFS, NFS, CDFS, etc...
 
The FTP proxy must allow PUT requests to go through for this to work on
top of FTP, but it might be useful when an HTTP proxy filters http URLs
(making it impossible to connect to the remote server at some *.dhis.org site,
e.g.), and don't filter FTP ones.
New file
/httptunnel/acinclude.m4
@@ -0,0 +1,36 @@
dnl HTTPTUNNEL_TYPE_SOCKLEN_T
dnl Check for the existance of type socklen_t.
 
AC_DEFUN(HTTPTUNNEL_TYPE_SOCKLEN_T,
[AC_CACHE_CHECK([for socklen_t], ac_cv_httptunnel_type_socklen_t,
[
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/socket.h>],
[socklen_t len = 42; return 0;],
ac_cv_httptunnel_type_socklen_t=yes,
ac_cv_httptunnel_type_socklen_t=no)
])
if test $ac_cv_httptunnel_type_socklen_t != yes; then
AC_DEFINE(socklen_t, int)
fi
])
 
 
dnl HTTPTUNNEL_DEFINE_INADDR_NONE
dnl Check for the existance of define INADDR_NONE
 
AC_DEFUN(HTTPTUNNEL_DEFINE_INADDR_NONE,
[AC_CACHE_CHECK([whether INADDR_NONE is defined], ac_cv_httptunnel_define_inaddr_none,
[
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <netinet/in.h>],
[return INADDR_NONE;],
ac_cv_httptunnel_define_inaddr_none=yes,
ac_cv_httptunnel_define_inaddr_none=no)
])
if test $ac_cv_httptunnel_define_inaddr_none != yes; then
AC_DEFINE(INADDR_NONE, 0xffffffff)
fi
])
New file
/httptunnel/FAQ
@@ -0,0 +1,94 @@
Q: I'm not real sure what httptunnel can be used for exactly?
 
A: It's a generic tool for sending data in and out through an HTTP proxy.
This is not very useful in itself, so you must run another program
which uses this data "tunnel". For example, you could use telnet
to log in on a computer ouside the proxy.
 
Q: httptunnel craches my SuSE 5.3 box, why?
 
A: I don't know, but upgrading to 6.0 seems to help.
 
Q: I'm responsible for network security in our company. My question
is: are there any characteristics of the communication that may be
detected at the proxy?
 
A: Maybe. I make no guarantees. Use the source.
 
Q: I wrote 'hts -d /dev/ptyq1' but 'cat </dev/ptyq1' returns an error.
 
A: Use 'cat </dev/ttyq1' instead.
 
Q: My friend runs hts at port 8888, but when I try to connect to it,
there is no response.
 
A: As for now, hts can't handle multiple tunnels. You must run your
own instance of hts listening to another port.
 
Q: Is there a Windows/95/98/NT version?
 
A: It's possible to build and run httptunnel in the Cygwin environment.
See http://sourceware.cygnus.com/cygwin/.
 
Q: Are there binaries of httptunnel for win32(Windows/95/98/NT) anywhere?
 
A: On the homepage, there is a link to someone maintaining
win32 binaries.
 
Q: Is there a Macintoch version?
 
A: Not that I know of.
 
Q: My firewall requires HTTP user authentication (which is currently
not supported by httptunnel). Do you plan to add something like
that?
 
A: Yes.
 
Q: How hard would it be to implement "hts" as a cgi running on a
normal web server?
 
A: hts can't be called directly from the HTTP server, because hts will
service many connections during the lifetime of the tunnel. If the
HTTP server executed a new instance of hts every time a new request
was made, each new hts wouldn't have access to the prior state of
the tunnel.
 
However, a CGI proxy which forwards the requests to a normal hts
listening to a port != 80 whould most probably be quite trivial to
implement.
 
Q: Have you thought of using HTTPS?
 
A: It has been suggested, but I'd rather avoid all the nasty export
restrictions. You can use external software to get an encrypted
tunnel.
 
Q: On REMOTE (brugd.ctrl-c.liu.se) I do the following:
hts -F localhost:23 8888
 
This worked the first time, but never since... now I only get:
hts: couldn't create tunnel
 
A: The first hts is still running in the background.
 
Q: On LOCAL (dhcp-XXX.enea.se) I do:
htc -F 2323 -P http://internwebb/proxy2.pac:8000 brugd.ctrl-c.liu.se:8888
 
Now, I try:
[root@localhost httptunnel-1.101]# telnet localhost 2323
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
 
A: [Christian Brideau] http://internwebb/proxy2.pac:8000 is not
exactly the proxy's adress. This is the location of the
Proxy-Auto-Configure (PAC) file. This file contains the adress of
the proxy server. To discover the real adress, just go to an
external web page using a browser and then use netstat to figure
out what adress your browser is using.
 
Q: Why does 'configure' fail on HP-UX?
 
A: Because you haven't installed gcc. If
CFLAGS=-O ./configure
doesn't work, you must get gcc, or at least an ANSI C compiler.
New file
/httptunnel/Makefile.am
@@ -0,0 +1,24 @@
## Copyright (C) 1999 Lars Brinkhoff
 
SUBDIRS = port
 
bin_PROGRAMS = htc hts
man_MANS = hts.1 htc.1
 
if SRCDIR
CPPFLAGS += -I$(VPATH)/port
else
CPPFLAGS += -Iport
endif
 
htc_SOURCES = htc.c common.c tunnel.c http.c base64.c
htc_LDADD = -Lport -lport
hts_SOURCES = hts.c common.c tunnel.c http.c
hts_LDADD = -Lport -lport
 
noinst_HEADERS = common.h tunnel.h http.h base64.h
 
EXTRA_DIST = TODO HACKING DISCLAIMER doc/rfc1945.txt doc/rfc2068.txt \
FAQ doc/rfc2045.txt hts.1 htc.1 debian/changelog debian/control \
debian/copyright debian/dirs debian/docs debian/rules \
debian/prerm debian/postinst
New file
/httptunnel/common.c
@@ -0,0 +1,403 @@
/*
common.c
 
Copyright (C) 1999, 2000 Lars Brinkhoff. See COPYING for terms and conditions.
 
Code common to both htc and hts.
*/
 
#include <time.h>
#include <stdio.h>
#include <netdb_.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog_.h>
#include <termios.h>
#include <sys/poll_.h>
 
#include "tunnel.h"
#include "common.h"
 
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
 
#ifdef DEBUG_MODE
static void
log_level (int level, char *fmt0, va_list ap)
{
if (debug_level >= level)
{
struct tm *t2;
char s[40];
time_t t;
int i;
 
time (&t);
t2 = localtime (&t);
strftime (s, sizeof s, "%Y%m%d %H%M%S ", t2);
fprintf (debug_file, "%s", s);
for (i = 1; i < level; i++)
fprintf (debug_file, " ");
vfprintf (debug_file, fmt0, ap);
fprintf (debug_file, "\n");
fflush (debug_file);
}
}
#endif
 
void
log_exit (int status)
{
log_notice ("exit with status = %d", status);
exit (status);
}
 
void
log_notice (char *fmt0, ...)
{
va_list ap;
va_start(ap, fmt0);
#ifdef DEBUG_MODE
log_level (1, fmt0, ap);
#else
vsyslog (LOG_NOTICE, fmt0, ap);
#endif
va_end(ap);
}
 
void
log_error (char *fmt0, ...)
{
va_list ap;
va_start(ap, fmt0);
#ifdef DEBUG_MODE
log_level (2, fmt0, ap);
#else
vsyslog (LOG_ERROR, fmt0, ap);
#endif
va_end(ap);
}
 
#ifdef DEBUG_MODE
void
log_debug (char *fmt0, ...)
{
va_list ap;
va_start(ap, fmt0);
log_level (3, fmt0, ap);
va_end(ap);
}
#endif
 
#ifdef DEBUG_MODE
void
log_verbose (char *fmt0, ...)
{
va_list ap;
va_start(ap, fmt0);
log_level (4, fmt0, ap);
va_end(ap);
}
#endif
 
#ifdef DEBUG_MODE
void
log_annoying (char *fmt0, ...)
{
va_list ap;
va_start (ap, fmt0);
log_level (5, fmt0, ap);
va_end(ap);
}
#endif
 
int
server_socket (struct in_addr addr, int port, int backlog)
{
struct sockaddr_in address;
int i, s;
 
s = socket (PF_INET, SOCK_STREAM, 0);
if (s == -1)
return -1;
i = 1;
if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, (void *)&i, sizeof i) == -1)
{
log_error ("server_socket: setsockopt SO_REUSEADDR: %s",
strerror (errno));
}
 
memset (&address, '\0', sizeof address);
#if defined(__FreeBSD__) || defined(__OpenBSD__)
address.sin_len = sizeof address;
#endif
address.sin_family = PF_INET;
address.sin_port = htons ((short)port);
address.sin_addr = addr;
if (bind (s, (struct sockaddr *)&address, sizeof (address)) == -1)
{
close (s);
return -1;
}
 
if (listen (s, (unsigned)backlog) == -1)
{
close (s);
return -1;
}
 
return s;
}
 
int
set_address (struct sockaddr_in *address, const char *host, int port)
{
memset (address, '\0', sizeof *address);
#if defined(__FreeBSD__) || defined(__OpenBSD__)
address->sin_len = sizeof *address;
#endif
address->sin_family = PF_INET;
address->sin_port = htons ((u_short)port);
address->sin_addr.s_addr = inet_addr (host);
 
if (address->sin_addr.s_addr == INADDR_NONE)
{
struct hostent *ent;
unsigned int ip;
 
log_annoying ("set_address: gethostbyname (\"%s\")", host);
ent = gethostbyname (host);
log_annoying ("set_address: ent = %p", ent);
if (ent == 0)
return -1;
 
memcpy(&address->sin_addr.s_addr, ent->h_addr, (unsigned)ent->h_length);
ip = ntohl (address->sin_addr.s_addr);
log_annoying ("set_address: host = %d.%d.%d.%d",
ntohl (ip) >> 24,
(ntohl (ip) >> 16) & 0xff,
(ntohl (ip) >> 8) & 0xff,
ntohl (ip) & 0xff);
}
 
return 0;
}
 
int
open_device (char *device)
{
struct termios t;
int fd;
 
fd = open (device, O_RDWR | O_NONBLOCK);
if (fd == -1)
return -1;
if (tcgetattr (fd, &t) == -1)
{
if (errno == ENOTTY || errno == EINVAL)
return fd;
else
return -1;
}
t.c_iflag = 0;
t.c_oflag = 0;
t.c_lflag = 0;
if (tcsetattr (fd, TCSANOW, &t) == -1)
return -1;
 
return fd;
}
 
#ifdef DEBUG_MODE
void
dump_buf (FILE *f, unsigned char *buf, size_t len)
{
const int N = 20;
int i, j;
 
for (i = 0; i < len;)
{
fputc ('[', f);
for (j = 0; j < N && i + j < len; j++)
fprintf (f, "%02x", buf[i + j]);
for (; j < N; j++)
fprintf (f, " ");
fputc (']', f);
fputc ('[', f);
for (j = 0; j < N && i + j < len; j++)
{
int c = buf[i + j];
if (c < ' ' || c > 126)
fputc ('.', f);
else
fputc (c, f);
}
fputc (']', f);
fputc ('\n', f);
i += j;
}
}
#endif
 
int
handle_device_input (Tunnel *tunnel, int fd, int events)
{
unsigned char buf[10240];
ssize_t n, m;
 
if (events & POLLIN)
{
n = read (fd, buf, sizeof buf);
if (n == 0 || n == -1)
{
if (n == -1 && errno != EAGAIN)
log_error ("handle_device_input: read() error: %s",
strerror (errno));
return n;
}
 
#ifdef DEBUG_MODE
log_annoying ("read %d bytes from device:", n);
if (debug_level >= 5)
dump_buf (debug_file, buf, (size_t)n);
#endif
 
m = tunnel_write (tunnel, buf, (size_t)n);
log_annoying ("tunnel_write (%p, %p, %d) = %d", tunnel, buf, n, m);
return m;
}
else if (events & POLLHUP)
{
log_error ("handle_device_input: POLLHUP");
sleep (5);
}
else if (events & POLLERR)
log_error ("handle_device_input: POLLERR");
else if (events & POLLNVAL)
log_error ("handle_device_input: POLLINVAL");
else
log_error ("handle_device_input: none of the above");
 
errno = EIO;
return -1;
}
 
int
handle_tunnel_input (Tunnel *tunnel, int fd, int events)
{
unsigned char buf[10240];
ssize_t n, m;
 
if (events & POLLIN)
{
n = tunnel_read (tunnel, buf, sizeof buf);
if (n <= 0)
{
log_annoying ("handle_tunnel_input: tunnel_read() = %d\n", n);
if (n == -1 && errno != EAGAIN)
log_error ("handle_tunnel_input: tunnel_read() error: %s",
strerror (errno));
return n;
}
 
#ifdef DEBUG_MODE
log_annoying ("read %d bytes from tunnel:", n);
if (debug_level >= 5)
dump_buf (debug_file, buf, (size_t)n);
#endif
 
/* If fd == 0, then we are using --stdin-stdout so write to stdout,
* not fd. */
m = write_all (fd ? fd : 0, buf, (size_t)n);
log_annoying ("write_all (%d, %p, %d) = %d", fd ? fd : 1, buf, n, m);
return m;
}
else if (events & POLLHUP)
log_error ("handle_device_input: POLLHUP");
else if (events & POLLERR)
log_error ("handle_device_input: PULLERR");
else if (events & POLLNVAL)
log_error ("handle_device_input: PULLINVAL");
else
log_error ("handle_device_input: none of the above");
 
errno = EIO;
return -1;
}
 
void
name_and_port (const char *nameport, char **name, int *port)
{
char *p;
 
*name = strdup (nameport);
if (*name == NULL)
{
fprintf (stderr, "Out of memory\n");
exit (1);
}
 
p = strchr (*name, ':');
if (p != NULL)
{
*port = atoi (p + 1);
*p = '\0';
}
}
 
int
atoi_with_postfix (const char *s_)
{
char *s = strdup (s_);
int n = strlen (s);
int factor = 1;
int x;
 
if (s == NULL)
{
fprintf (stderr, "Out of memory\n");
exit (1);
}
 
switch (s[n - 1])
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
break;
case 'k':
case 'K':
factor = 1024;
break;
case 'M':
factor = 1024 * 1024;
break;
case 'G':
factor = 1024 * 1024 * 1024;
break;
default:
fprintf (stderr, "Unknown postfix: %c\n", s[n - 1]);
exit (1);
}
 
if (factor != 1)
s[n - 1] = '\0';
 
x = factor * atoi (s);
free (s);
return x;
}
 
#ifdef DEBUG_MODE
RETSIGTYPE
log_sigpipe (int sig)
{
log_debug ("caught SIGPIPE");
signal (SIGPIPE, log_sigpipe);
}
#endif
New file
/httptunnel/missing
@@ -0,0 +1,190 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
 
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
 
case "$1" in
 
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
 
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
 
Options:
-h, --help display this help and exit
-v, --version output version information and exit
 
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
 
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing - GNU libit 0.0"
;;
 
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
 
aclocal)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`configure.in'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
 
autoconf)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`configure.in'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
 
autoheader)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`configure.in'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
 
automake)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
 
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
 
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
 
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
 
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequirements for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
 
exit 0
New file
/httptunnel/base64.h
@@ -0,0 +1,9 @@
/*
base64.h
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#include <sys/types.h>
 
ssize_t encode_base64 (const void *data, size_t length, char **code);
 
New file
/httptunnel/DISCLAIMER
@@ -0,0 +1,6 @@
I hereby disclaim all responsibility for this hack. If it backfires on
you in any way whatsoever, that's the breaks. Not my fault. If you
don't understand the risks inherent in doing this, don't do it. If you
use this hack and it allows vicious vandals to break into your
company's computers and costs you your job and your company millions
of dollars, well that's just tough nuggies. Don't come crying to me.
New file
/httptunnel/aclocal.m4
@@ -0,0 +1,177 @@
dnl aclocal.m4 generated automatically by aclocal 1.4
 
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
 
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
 
dnl HTTPTUNNEL_TYPE_SOCKLEN_T
dnl Check for the existance of type socklen_t.
 
AC_DEFUN(HTTPTUNNEL_TYPE_SOCKLEN_T,
[AC_CACHE_CHECK([for socklen_t], ac_cv_httptunnel_type_socklen_t,
[
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <sys/socket.h>],
[socklen_t len = 42; return 0;],
ac_cv_httptunnel_type_socklen_t=yes,
ac_cv_httptunnel_type_socklen_t=no)
])
if test $ac_cv_httptunnel_type_socklen_t != yes; then
AC_DEFINE(socklen_t, int)
fi
])
 
 
dnl HTTPTUNNEL_DEFINE_INADDR_NONE
dnl Check for the existance of define INADDR_NONE
 
AC_DEFUN(HTTPTUNNEL_DEFINE_INADDR_NONE,
[AC_CACHE_CHECK([whether INADDR_NONE is defined], ac_cv_httptunnel_define_inaddr_none,
[
AC_TRY_COMPILE(
[#include <sys/types.h>
#include <netinet/in.h>],
[return INADDR_NONE;],
ac_cv_httptunnel_define_inaddr_none=yes,
ac_cv_httptunnel_define_inaddr_none=no)
])
if test $ac_cv_httptunnel_define_inaddr_none != yes; then
AC_DEFINE(INADDR_NONE, 0xffffffff)
fi
])
 
# Do all the work for Automake. This macro actually does too much --
# some checks are only needed if your package does certain things.
# But this isn't really a big deal.
 
# serial 1
 
dnl Usage:
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
 
AC_DEFUN(AM_INIT_AUTOMAKE,
[AC_REQUIRE([AC_PROG_INSTALL])
PACKAGE=[$1]
AC_SUBST(PACKAGE)
VERSION=[$2]
AC_SUBST(VERSION)
dnl test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
ifelse([$3],,
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
AC_REQUIRE([AM_SANITY_CHECK])
AC_REQUIRE([AC_ARG_PROGRAM])
dnl FIXME This is truly gross.
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
AC_REQUIRE([AC_PROG_MAKE_SET])])
 
#
# Check to make sure that the build environment is sane.
#
 
AC_DEFUN(AM_SANITY_CHECK,
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftestfile
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
if test "[$]*" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftestfile`
fi
if test "[$]*" != "X $srcdir/configure conftestfile" \
&& test "[$]*" != "X conftestfile $srcdir/configure"; then
 
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
 
test "[$]2" = conftestfile
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
rm -f conftest*
AC_MSG_RESULT(yes)])
 
dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
dnl The program must properly implement --version.
AC_DEFUN(AM_MISSING_PROG,
[AC_MSG_CHECKING(for working $2)
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if ($2 --version) < /dev/null > /dev/null 2>&1; then
$1=$2
AC_MSG_RESULT(found)
else
$1="$3/missing $2"
AC_MSG_RESULT(missing)
fi
AC_SUBST($1)])
 
# Like AC_CONFIG_HEADER, but automatically create stamp file.
 
AC_DEFUN(AM_CONFIG_HEADER,
[AC_PREREQ([2.12])
AC_CONFIG_HEADER([$1])
dnl When config.status generates a header, we must update the stamp-h file.
dnl This file resides in the same directory as the config header
dnl that is generated. We must strip everything past the first ":",
dnl and everything past the last "/".
AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
<<am_indx=1
for am_file in <<$1>>; do
case " <<$>>CONFIG_HEADERS " in
*" <<$>>am_file "*<<)>>
echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
;;
esac
am_indx=`expr "<<$>>am_indx" + 1`
done<<>>dnl>>)
changequote([,]))])
 
# Define a conditional.
 
AC_DEFUN(AM_CONDITIONAL,
[AC_SUBST($1_TRUE)
AC_SUBST($1_FALSE)
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi])
 
New file
/httptunnel/common.h
@@ -0,0 +1,170 @@
/*
common.h
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#ifndef COMMON_H
#define COMMON_H
 
#include "config.h"
 
#include <errno.h>
#include <fcntl.h>
#include <stdio_.h>
#include <unistd_.h>
#include <string.h>
#include <syslog_.h>
#include <getopt.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdarg.h>
 
#include "tunnel.h"
 
#define DEFAULT_HOST_PORT 8888
#define DEFAULT_CONTENT_LENGTH (100 * 1024) /* bytes */
#define DEFAULT_KEEP_ALIVE 5 /* seconds */
#define DEFAULT_MAX_CONNECTION_AGE 300 /* seconds */
#define BUG_REPORT_EMAIL "bug-httptunnel@gnu.org"
 
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
 
#if defined (LOG_ERR) && !defined (LOG_ERROR)
#define LOG_ERROR LOG_ERR
#endif
 
extern int debug_level;
extern FILE *debug_file;
 
extern void log_exit (int status);
extern void log_notice (char *fmt0, ...);
extern void log_error (char *fmt0, ...);
#ifdef DEBUG_MODE
extern void log_debug (char *fmt0, ...);
extern void log_verbose (char *fmt0, ...);
extern void log_annoying (char *fmt0, ...);
#else
static inline void log_debug () {}
static inline void log_verbose () {}
static inline void log_annoying () {}
#endif
 
extern int server_socket (struct in_addr addr, int port, int backlog);
extern int set_address (struct sockaddr_in *address,
const char *host, int port);
extern int open_device (char *device);
extern int handle_device_input (Tunnel *tunnel, int fd, int events);
extern int handle_tunnel_input (Tunnel *tunnel, int fd, int events);
extern void name_and_port (const char *nameport, char **name, int *port);
extern int atoi_with_postfix (const char *s_);
extern RETSIGTYPE log_sigpipe (int);
void dump_buf (FILE *f, unsigned char *buf, size_t len);
 
static inline ssize_t
read_all (int fd, void *buf, size_t len)
{
ssize_t n, m, r;
long flags;
char *rbuf = buf;
 
flags = fcntl (fd, F_GETFL);
fcntl (fd, F_SETFL, flags & ~O_NONBLOCK);
 
r = len;
for (n = 0; n < len; n += m)
{
log_annoying ("read (%d, %p, %d) ...", fd, rbuf + n, len - n);
m = read (fd, rbuf + n, len - n);
log_annoying ("... = %d", m);
if (m == 0)
{
r = 0;
break;
}
else if (m == -1)
{
if (errno != EAGAIN)
{
r = -1;
break;
}
else
m = 0;
}
}
 
fcntl (fd, F_SETFL, flags);
return r;
}
 
static inline ssize_t
write_all (int fd, void *data, size_t len)
{
ssize_t n, m;
char *wdata = data;
 
for (n = 0; n < len; n += m)
{
log_annoying ("write (%d, %p, %d) ...", fd, wdata + n, len - n);
m = write (fd, wdata + n, len - n);
log_annoying ("... = %d", m);
if (m == 0)
return 0;
else if (m == -1)
{
if (errno != EAGAIN)
return -1;
else
m = 0;
}
}
 
return len;
}
 
static inline int
do_connect (struct sockaddr_in *address)
{
int fd;
 
fd = socket (AF_INET, SOCK_STREAM, 0);
if (fd == -1)
return -1;
 
if (connect (fd, (struct sockaddr *)address,
sizeof (struct sockaddr_in)) == -1)
{
close (fd);
return -1;
}
 
return fd;
}
 
static inline void
handle_input (const char *type, Tunnel *tunnel, int fd, int events,
int (*handler)(Tunnel *tunnel, int fd, int events),
int *closed)
{
if (events)
{
ssize_t n;
 
n = handler (tunnel, fd, events);
if (n == 0 || (n == -1 && errno != EAGAIN))
{
if (n == 0)
log_debug ("%s closed", type);
else
log_error ("%s read error: %s", type, strerror (errno));
*closed = TRUE;
}
}
}
 
#endif /* COMMON_H */
New file
/httptunnel/install-sh
@@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
 
 
# set DOITPROG to echo to test this script
 
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
 
 
# put in absolute paths if you don't have them in your path; or use env. vars.
 
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
 
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
 
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
 
-d) dir_arg=true
shift
continue;;
 
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
 
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
 
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
 
-s) stripcmd="$stripprog"
shift
continue;;
 
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
 
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
 
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
 
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
 
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
 
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
 
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
 
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
 
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
 
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
 
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
 
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
 
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
 
pathcomp=''
 
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
 
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
 
pathcomp="${pathcomp}/"
done
fi
 
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
 
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
 
# If we're going to rename the final executable, determine the name now.
 
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
 
# don't allow the sed command to completely eliminate the filename
 
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
 
# Make a temp file name in the proper directory.
 
dsttmp=$dstdir/#inst.$$#
 
# Move or copy the file name to the temp name
 
$doit $instcmd $src $dsttmp &&
 
trap "rm -f ${dsttmp}" 0 &&
 
# and set any options; do chmod last to preserve setuid bits
 
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
 
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
 
# Now rename the file to the real destination.
 
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
 
fi &&
 
 
exit 0
New file
/httptunnel/configure
@@ -0,0 +1,2699 @@
#! /bin/sh
 
# Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf version 2.13
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
 
# Defaults:
ac_help=
ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
--enable-debug enable debugging"
 
# Initialize some variables set by options.
# The variables have the same names as the options, with
# dashes changed to underlines.
build=NONE
cache_file=./config.cache
exec_prefix=NONE
host=NONE
no_create=
nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
 
# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Maximum number of lines to put in a shell here document.
ac_max_here_lines=12
 
ac_prev=
for ac_option
do
 
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
ac_prev=
continue
fi
 
case "$ac_option" in
-*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) ac_optarg= ;;
esac
 
# Accept the important Cygnus configure options, so we can diagnose typos.
 
case "$ac_option" in
 
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
bindir="$ac_optarg" ;;
 
-build | --build | --buil | --bui | --bu)
ac_prev=build ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
build="$ac_optarg" ;;
 
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
cache_file="$ac_optarg" ;;
 
-datadir | --datadir | --datadi | --datad | --data | --dat | --da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
| --da=*)
datadir="$ac_optarg" ;;
 
-disable-* | --disable-*)
ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
{ echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
eval "enable_${ac_feature}=no" ;;
 
-enable-* | --enable-*)
ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
{ echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
case "$ac_option" in
*=*) ;;
*) ac_optarg=yes ;;
esac
eval "enable_${ac_feature}='$ac_optarg'" ;;
 
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
| --exec | --exe | --ex)
ac_prev=exec_prefix ;;
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
exec_prefix="$ac_optarg" ;;
 
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
 
-help | --help | --hel | --he)
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat << EOF
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
--cache-file=FILE cache test results in FILE
--help print this message
--no-create do not create output files
--quiet, --silent do not print \`checking...' messages
--version print the version of autoconf that created configure
Directory and file names:
--prefix=PREFIX install architecture-independent files in PREFIX
[$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[same as prefix]
--bindir=DIR user executables in DIR [EPREFIX/bin]
--sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
--libexecdir=DIR program executables in DIR [EPREFIX/libexec]
--datadir=DIR read-only architecture-independent data in DIR
[PREFIX/share]
--sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data in DIR
[PREFIX/com]
--localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
--libdir=DIR object code libraries in DIR [EPREFIX/lib]
--includedir=DIR C header files in DIR [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
--infodir=DIR info documentation in DIR [PREFIX/info]
--mandir=DIR man documentation in DIR [PREFIX/man]
--srcdir=DIR find the sources in DIR [configure dir or ..]
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
--program-transform-name=PROGRAM
run sed PROGRAM on installed program names
EOF
cat << EOF
Host type:
--build=BUILD configure for building on BUILD [BUILD=HOST]
--host=HOST configure for HOST [guessed]
--target=TARGET configure for TARGET [TARGET=HOST]
Features and packages:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--x-includes=DIR X include files are in DIR
--x-libraries=DIR X library files are in DIR
EOF
if test -n "$ac_help"; then
echo "--enable and --with options recognized:$ac_help"
fi
exit 0 ;;
 
-host | --host | --hos | --ho)
ac_prev=host ;;
-host=* | --host=* | --hos=* | --ho=*)
host="$ac_optarg" ;;
 
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
includedir="$ac_optarg" ;;
 
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
infodir="$ac_optarg" ;;
 
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
libdir="$ac_optarg" ;;
 
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
libexecdir="$ac_optarg" ;;
 
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
| --locals | --local | --loca | --loc | --lo)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
localstatedir="$ac_optarg" ;;
 
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
mandir="$ac_optarg" ;;
 
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
 
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c)
no_create=yes ;;
 
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
no_recursion=yes ;;
 
-oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
| --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
| --oldin | --oldi | --old | --ol | --o)
ac_prev=oldincludedir ;;
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
oldincludedir="$ac_optarg" ;;
 
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
prefix="$ac_optarg" ;;
 
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
program_prefix="$ac_optarg" ;;
 
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
program_suffix="$ac_optarg" ;;
 
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
| --program-transform-n | --program-transform- \
| --program-transform | --program-transfor \
| --program-transfo | --program-transf \
| --program-trans | --program-tran \
| --progr-tra | --program-tr | --program-t)
ac_prev=program_transform_name ;;
-program-transform-name=* | --program-transform-name=* \
| --program-transform-nam=* | --program-transform-na=* \
| --program-transform-n=* | --program-transform-=* \
| --program-transform=* | --program-transfor=* \
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
program_transform_name="$ac_optarg" ;;
 
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
 
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
sbindir="$ac_optarg" ;;
 
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
| --sharedst | --shareds | --shared | --share | --shar \
| --sha | --sh)
ac_prev=sharedstatedir ;;
-sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
sharedstatedir="$ac_optarg" ;;
 
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
site="$ac_optarg" ;;
 
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
srcdir="$ac_optarg" ;;
 
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
sysconfdir="$ac_optarg" ;;
 
-target | --target | --targe | --targ | --tar | --ta | --t)
ac_prev=target ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
target="$ac_optarg" ;;
 
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
 
-version | --version | --versio | --versi | --vers)
echo "configure generated by autoconf version 2.13"
exit 0 ;;
 
-with-* | --with-*)
ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
{ echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
case "$ac_option" in
*=*) ;;
*) ac_optarg=yes ;;
esac
eval "with_${ac_package}='$ac_optarg'" ;;
 
-without-* | --without-*)
ac_package=`echo $ac_option|sed -e 's/-*without-//'`
# Reject names that are not valid shell variable names.
if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
{ echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
eval "with_${ac_package}=no" ;;
 
--x)
# Obsolete; use --with-x.
with_x=yes ;;
 
-x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
| --x-incl | --x-inc | --x-in | --x-i)
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
x_includes="$ac_optarg" ;;
 
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries="$ac_optarg" ;;
 
-*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
;;
 
*)
if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
echo "configure: warning: $ac_option: invalid host type" 1>&2
fi
if test "x$nonopt" != xNONE; then
{ echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
fi
nonopt="$ac_option"
;;
 
esac
done
 
if test -n "$ac_prev"; then
{ echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
fi
 
trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
 
# File descriptor usage:
# 0 standard input
# 1 file creation
# 2 errors and warnings
# 3 some systems may open it to /dev/tty
# 4 used on the Kubota Titan
# 6 checking for... messages and results
# 5 compiler messages saved in config.log
if test "$silent" = yes; then
exec 6>/dev/null
else
exec 6>&1
fi
exec 5>./config.log
 
echo "\
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
" 1>&5
 
# Strip out --no-create and --no-recursion so they do not pile up.
# Also quote any args containing shell metacharacters.
ac_configure_args=
for ac_arg
do
case "$ac_arg" in
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c) ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
*" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
ac_configure_args="$ac_configure_args '$ac_arg'" ;;
*) ac_configure_args="$ac_configure_args $ac_arg" ;;
esac
done
 
# NLS nuisances.
# Only set these to C if already set. These must not be set unconditionally
# because not all systems understand e.g. LANG=C (notably SCO).
# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}" = set; then LANG=C; export LANG; fi
if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
 
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo > confdefs.h
 
# A filename unique to this package, relative to the directory that
# configure is in, which we can look for to find out if srcdir is correct.
ac_unique_file=tunnel.c
 
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then its parent.
ac_prog=$0
ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
{ echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
else
{ echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
fi
fi
srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
 
# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
if test "x$prefix" != xNONE; then
CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
else
CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
fi
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
echo "loading site script $ac_site_file"
. "$ac_site_file"
fi
done
 
if test -r "$cache_file"; then
echo "loading cache $cache_file"
. $cache_file
else
echo "creating cache $cache_file"
> $cache_file
fi
 
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
 
ac_exeext=
ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
ac_n= ac_c='
' ac_t=' '
else
ac_n=-n ac_c= ac_t=
fi
else
ac_n= ac_c='\c' ac_t=
fi
 
 
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install-sh -c"
break
elif test -f $ac_dir/install.sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install.sh -c"
break
fi
done
if test -z "$ac_aux_dir"; then
{ echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
fi
ac_config_guess=$ac_aux_dir/config.guess
ac_config_sub=$ac_aux_dir/config.sub
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:558: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
# Don't use installbsd from OSF since it installs stuff as root
# by default.
for ac_prog in ginstall scoinst install; do
if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
:
else
ac_cv_path_install="$ac_dir/$ac_prog -c"
break 2
fi
fi
done
;;
esac
done
IFS="$ac_save_IFS"
 
fi
if test "${ac_cv_path_install+set}" = set; then
INSTALL="$ac_cv_path_install"
else
# As a last resort, use the slow shell script. We don't cache a
# path for INSTALL within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the path is relative.
INSTALL="$ac_install_sh"
fi
fi
echo "$ac_t""$INSTALL" 1>&6
 
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
 
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
echo "configure:611: checking whether build environment is sane" >&5
# Just in case
sleep 1
echo timestamp > conftestfile
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
if test "$*" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftestfile`
fi
if test "$*" != "X $srcdir/configure conftestfile" \
&& test "$*" != "X conftestfile $srcdir/configure"; then
 
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
{ echo "configure: error: ls -t appears to fail. Make sure there is not a broken
alias in your environment" 1>&2; exit 1; }
fi
 
test "$2" = conftestfile
)
then
# Ok.
:
else
{ echo "configure: error: newly created file is older than distributed files!
Check your system clock" 1>&2; exit 1; }
fi
rm -f conftest*
echo "$ac_t""yes" 1>&6
if test "$program_transform_name" = s,x,x,; then
program_transform_name=
else
# Double any \ or $. echo might interpret backslashes.
cat <<\EOF_SED > conftestsed
s,\\,\\\\,g; s,\$,$$,g
EOF_SED
program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
rm -f conftestsed
fi
test "$program_prefix" != NONE &&
program_transform_name="s,^,${program_prefix},; $program_transform_name"
# Use a double $ so make ignores it.
test "$program_suffix" != NONE &&
program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
 
# sed with no file args requires a program.
test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
echo "configure:668: checking whether ${MAKE-make} sets \${MAKE}" >&5
set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftestmake <<\EOF
all:
@echo 'ac_maketemp="${MAKE}"'
EOF
# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
if test -n "$ac_maketemp"; then
eval ac_cv_prog_make_${ac_make}_set=yes
else
eval ac_cv_prog_make_${ac_make}_set=no
fi
rm -f conftestmake
fi
if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
echo "$ac_t""yes" 1>&6
SET_MAKE=
else
echo "$ac_t""no" 1>&6
SET_MAKE="MAKE=${MAKE-make}"
fi
 
 
PACKAGE=httptunnel
 
VERSION=3.3
 
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
{ echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
fi
cat >> confdefs.h <<EOF
#define PACKAGE "$PACKAGE"
EOF
 
cat >> confdefs.h <<EOF
#define VERSION "$VERSION"
EOF
 
 
 
missing_dir=`cd $ac_aux_dir && pwd`
echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
echo "configure:714: checking for working aclocal" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if (aclocal --version) < /dev/null > /dev/null 2>&1; then
ACLOCAL=aclocal
echo "$ac_t""found" 1>&6
else
ACLOCAL="$missing_dir/missing aclocal"
echo "$ac_t""missing" 1>&6
fi
 
echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
echo "configure:727: checking for working autoconf" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if (autoconf --version) < /dev/null > /dev/null 2>&1; then
AUTOCONF=autoconf
echo "$ac_t""found" 1>&6
else
AUTOCONF="$missing_dir/missing autoconf"
echo "$ac_t""missing" 1>&6
fi
 
echo $ac_n "checking for working automake""... $ac_c" 1>&6
echo "configure:740: checking for working automake" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if (automake --version) < /dev/null > /dev/null 2>&1; then
AUTOMAKE=automake
echo "$ac_t""found" 1>&6
else
AUTOMAKE="$missing_dir/missing automake"
echo "$ac_t""missing" 1>&6
fi
 
echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
echo "configure:753: checking for working autoheader" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if (autoheader --version) < /dev/null > /dev/null 2>&1; then
AUTOHEADER=autoheader
echo "$ac_t""found" 1>&6
else
AUTOHEADER="$missing_dir/missing autoheader"
echo "$ac_t""missing" 1>&6
fi
 
echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
echo "configure:766: checking for working makeinfo" >&5
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
MAKEINFO=makeinfo
echo "$ac_t""found" 1>&6
else
MAKEINFO="$missing_dir/missing makeinfo"
echo "$ac_t""missing" 1>&6
fi
 
 
 
 
 
 
 
 
if test "x$srcdir" != x.; then
SRCDIR_TRUE=
SRCDIR_FALSE='#'
else
SRCDIR_TRUE='#'
SRCDIR_FALSE=
fi
 
# Check whether --enable-debug or --disable-debug was given.
if test "${enable_debug+set}" = set; then
enableval="$enable_debug"
cat >> confdefs.h <<\EOF
#define DEBUG_MODE 1
EOF
 
fi
 
 
if test "x$CFLAGS" = x; then
if test "x$enable_debug" != x; then
CFLAGS="-g -Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith"
else
CFLAGS="-O2 -Wall -fomit-frame-pointer"
fi
fi
 
for ac_prog in mawk gawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:816: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$AWK"; then
ac_cv_prog_AWK="$AWK" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_AWK="$ac_prog"
break
fi
done
IFS="$ac_save_ifs"
fi
fi
AWK="$ac_cv_prog_AWK"
if test -n "$AWK"; then
echo "$ac_t""$AWK" 1>&6
else
echo "$ac_t""no" 1>&6
fi
 
test -n "$AWK" && break
done
 
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:848: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="gcc"
break
fi
done
IFS="$ac_save_ifs"
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no" 1>&6
fi
 
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:878: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
fi
ac_cv_prog_CC="cc"
break
fi
done
IFS="$ac_save_ifs"
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
if test $# -gt 0; then
# We chose a different compiler from the bogus one.
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
set dummy "$ac_dir/$ac_word" "$@"
shift
ac_cv_prog_CC="$@"
fi
fi
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no" 1>&6
fi
 
if test -z "$CC"; then
case "`uname -s`" in
*win32* | *WIN32*)
# Extract the first word of "cl", so it can be a program name with args.
set dummy cl; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:929: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="cl"
break
fi
done
IFS="$ac_save_ifs"
fi
fi
CC="$ac_cv_prog_CC"
if test -n "$CC"; then
echo "$ac_t""$CC" 1>&6
else
echo "$ac_t""no" 1>&6
fi
;;
esac
fi
test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi
 
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:961: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
 
cat > conftest.$ac_ext << EOF
 
#line 972 "configure"
#include "confdefs.h"
 
main(){return(0);}
EOF
if { (eval echo configure:977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
ac_cv_prog_cc_cross=no
else
ac_cv_prog_cc_cross=yes
fi
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_prog_cc_works=no
fi
rm -fr conftest*
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
 
echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:1003: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
 
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
echo "configure:1008: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.c <<EOF
#ifdef __GNUC__
yes;
#endif
EOF
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1017: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
fi
fi
 
echo "$ac_t""$ac_cv_prog_gcc" 1>&6
 
if test $ac_cv_prog_gcc = yes; then
GCC=yes
else
GCC=
fi
 
ac_test_CFLAGS="${CFLAGS+set}"
ac_save_CFLAGS="$CFLAGS"
CFLAGS=
echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
echo "configure:1036: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo 'void f(){}' > conftest.c
if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
ac_cv_prog_cc_g=yes
else
ac_cv_prog_cc_g=no
fi
rm -f conftest*
 
fi
 
echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
if test "$ac_test_CFLAGS" = set; then
CFLAGS="$ac_save_CFLAGS"
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
else
CFLAGS="-g"
fi
else
if test "$GCC" = yes; then
CFLAGS="-O2"
else
CFLAGS=
fi
fi
 
if test "$program_transform_name" = s,x,x,; then
program_transform_name=
else
# Double any \ or $. echo might interpret backslashes.
cat <<\EOF_SED > conftestsed
s,\\,\\\\,g; s,\$,$$,g
EOF_SED
program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
rm -f conftestsed
fi
test "$program_prefix" != NONE &&
program_transform_name="s,^,${program_prefix},; $program_transform_name"
# Use a double $ so make ignores it.
test "$program_suffix" != NONE &&
program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
 
# sed with no file args requires a program.
test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
echo "configure:1098: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
# Don't use installbsd from OSF since it installs stuff as root
# by default.
for ac_prog in ginstall scoinst install; do
if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
:
else
ac_cv_path_install="$ac_dir/$ac_prog -c"
break 2
fi
fi
done
;;
esac
done
IFS="$ac_save_IFS"
 
fi
if test "${ac_cv_path_install+set}" = set; then
INSTALL="$ac_cv_path_install"
else
# As a last resort, use the slow shell script. We don't cache a
# path for INSTALL within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the path is relative.
INSTALL="$ac_install_sh"
fi
fi
echo "$ac_t""$INSTALL" 1>&6
 
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
 
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
echo "configure:1151: checking whether ln -s works" >&5
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
rm -f conftestdata
if ln -s X conftestdata 2>/dev/null
then
rm -f conftestdata
ac_cv_prog_LN_S="ln -s"
else
ac_cv_prog_LN_S=ln
fi
fi
LN_S="$ac_cv_prog_LN_S"
if test "$ac_cv_prog_LN_S" = "ln -s"; then
echo "$ac_t""yes" 1>&6
else
echo "$ac_t""no" 1>&6
fi
 
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1174: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_dummy="$PATH"
for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_RANLIB="ranlib"
break
fi
done
IFS="$ac_save_ifs"
test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
fi
fi
RANLIB="$ac_cv_prog_RANLIB"
if test -n "$RANLIB"; then
echo "$ac_t""$RANLIB" 1>&6
else
echo "$ac_t""no" 1>&6
fi
 
 
echo $ac_n "checking for gethostent""... $ac_c" 1>&6
echo "configure:1203: checking for gethostent" >&5
if eval "test \"`echo '$''{'ac_cv_func_gethostent'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1208 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostent(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char gethostent();
 
int main() {
 
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_gethostent) || defined (__stub___gethostent)
choke me
#else
gethostent();
#endif
 
; return 0; }
EOF
if { (eval echo configure:1231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_gethostent=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_gethostent=no"
fi
rm -f conftest*
fi
 
if eval "test \"`echo '$ac_cv_func_'gethostent`\" = yes"; then
echo "$ac_t""yes" 1>&6
:
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for gethostent in -lnsl""... $ac_c" 1>&6
echo "configure:1249: checking for gethostent in -lnsl" >&5
ac_lib_var=`echo nsl'_'gethostent | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1257 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char gethostent();
 
int main() {
gethostent()
; return 0; }
EOF
if { (eval echo configure:1268: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
 
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/^a-zA-Z0-9_/_/g' \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
cat >> confdefs.h <<EOF
#define $ac_tr_lib 1
EOF
 
LIBS="-lnsl $LIBS"
 
else
echo "$ac_t""no" 1>&6
fi
 
fi
 
echo $ac_n "checking for setsockopt""... $ac_c" 1>&6
echo "configure:1298: checking for setsockopt" >&5
if eval "test \"`echo '$''{'ac_cv_func_setsockopt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1303 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char setsockopt(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char setsockopt();
 
int main() {
 
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_setsockopt) || defined (__stub___setsockopt)
choke me
#else
setsockopt();
#endif
 
; return 0; }
EOF
if { (eval echo configure:1326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_setsockopt=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_setsockopt=no"
fi
rm -f conftest*
fi
 
if eval "test \"`echo '$ac_cv_func_'setsockopt`\" = yes"; then
echo "$ac_t""yes" 1>&6
:
else
echo "$ac_t""no" 1>&6
echo $ac_n "checking for setsockopt in -lsocket""... $ac_c" 1>&6
echo "configure:1344: checking for setsockopt in -lsocket" >&5
ac_lib_var=`echo socket'_'setsockopt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1352 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char setsockopt();
 
int main() {
setsockopt()
; return 0; }
EOF
if { (eval echo configure:1363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"
 
fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/^a-zA-Z0-9_/_/g' \
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
cat >> confdefs.h <<EOF
#define $ac_tr_lib 1
EOF
 
LIBS="-lsocket $LIBS"
 
else
echo "$ac_t""no" 1>&6
fi
 
fi
 
 
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:1394: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
# This must be in double quotes, not single quotes, because CPP may get
# substituted into the Makefile and "${CC-cc}" will confuse make.
CPP="${CC-cc} -E"
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
#line 1409 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1415: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1426 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1432: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
#line 1443 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1449: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
:
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
CPP=/lib/cpp
fi
rm -f conftest*
fi
rm -f conftest*
fi
rm -f conftest*
ac_cv_prog_CPP="$CPP"
fi
CPP="$ac_cv_prog_CPP"
else
ac_cv_prog_CPP="$CPP"
fi
echo "$ac_t""$CPP" 1>&6
 
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
echo "configure:1474: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1479 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1487: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
ac_cv_header_stdc=yes
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_header_stdc=no
fi
rm -f conftest*
 
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
#line 1504 "configure"
#include "confdefs.h"
#include <string.h>
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "memchr" >/dev/null 2>&1; then
:
else
rm -rf conftest*
ac_cv_header_stdc=no
fi
rm -f conftest*
 
fi
 
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
#line 1522 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "free" >/dev/null 2>&1; then
:
else
rm -rf conftest*
ac_cv_header_stdc=no
fi
rm -f conftest*
 
fi
 
if test $ac_cv_header_stdc = yes; then
# /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
#line 1543 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
int main () { int i; for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
 
EOF
if { (eval echo configure:1554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
ac_cv_header_stdc=no
fi
rm -fr conftest*
fi
 
fi
fi
 
echo "$ac_t""$ac_cv_header_stdc" 1>&6
if test $ac_cv_header_stdc = yes; then
cat >> confdefs.h <<\EOF
#define STDC_HEADERS 1
EOF
 
fi
 
for ac_hdr in fcntl.h syslog.h unistd.h sys/poll.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
echo "configure:1581: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1586 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:1591: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
else
echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
cat >> confdefs.h <<EOF
#define $ac_tr_hdr 1
EOF
else
echo "$ac_t""no" 1>&6
fi
done
 
 
echo $ac_n "checking for working const""... $ac_c" 1>&6
echo "configure:1619: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1624 "configure"
#include "confdefs.h"
 
int main() {
 
/* Ultrix mips cc rejects this. */
typedef int charset[2]; const charset x = {0,0};
/* SunOS 4.1.1 cc rejects this. */
char const *const *ccp;
char **p;
/* NEC SVR4.0.2 mips cc rejects this. */
struct point {int x, y;};
static struct point const zero = {0,0};
/* AIX XL C 1.02.0.0 rejects this.
It does not let you subtract one const X* pointer from another in an arm
of an if-expression whose if-part is not a constant expression */
const char *g = "string";
ccp = &g + (g ? g-g : 0);
/* HPUX 7.0 cc rejects these. */
++ccp;
p = (char**) ccp;
ccp = (char const *const *) p;
{ /* SCO 3.2v4 cc rejects this. */
char *t;
char const *s = 0 ? (char *) 0 : (char const *) 0;
 
*t++ = 0;
}
{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
int x[] = {25, 17};
const int *foo = &x[0];
++foo;
}
{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
typedef const int *iptr;
iptr p = 0;
++p;
}
{ /* AIX XL C 1.02.0.0 rejects this saying
"k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
struct s { int j; const int *ap[3]; };
struct s *b; b->j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
}
 
; return 0; }
EOF
if { (eval echo configure:1673: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_c_const=no
fi
rm -f conftest*
fi
 
echo "$ac_t""$ac_cv_c_const" 1>&6
if test $ac_cv_c_const = no; then
cat >> confdefs.h <<\EOF
#define const
EOF
 
fi
 
echo $ac_n "checking for inline""... $ac_c" 1>&6
echo "configure:1694: checking for inline" >&5
if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF
#line 1701 "configure"
#include "confdefs.h"
 
int main() {
} int $ac_kw foo() {
; return 0; }
EOF
if { (eval echo configure:1708: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest*
done
 
fi
 
echo "$ac_t""$ac_cv_c_inline" 1>&6
case "$ac_cv_c_inline" in
inline | yes) ;;
no) cat >> confdefs.h <<\EOF
#define inline
EOF
;;
*) cat >> confdefs.h <<EOF
#define inline $ac_cv_c_inline
EOF
;;
esac
 
echo $ac_n "checking for size_t""... $ac_c" 1>&6
echo "configure:1734: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1739 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
#include <stdlib.h>
#include <stddef.h>
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_size_t=yes
else
rm -rf conftest*
ac_cv_type_size_t=no
fi
rm -f conftest*
 
fi
echo "$ac_t""$ac_cv_type_size_t" 1>&6
if test $ac_cv_type_size_t = no; then
cat >> confdefs.h <<\EOF
#define size_t unsigned
EOF
 
fi
 
##AC_CHECK_TYPE(socklen_t, unsigned) # doesn't search <sys/socket.h>
echo $ac_n "checking for socklen_t""... $ac_c" 1>&6
echo "configure:1768: checking for socklen_t" >&5
if eval "test \"`echo '$''{'ac_cv_httptunnel_type_socklen_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1774 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/socket.h>
int main() {
socklen_t len = 42; return 0;
; return 0; }
EOF
if { (eval echo configure:1782: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_httptunnel_type_socklen_t=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_httptunnel_type_socklen_t=no
fi
rm -f conftest*
 
fi
 
echo "$ac_t""$ac_cv_httptunnel_type_socklen_t" 1>&6
if test $ac_cv_httptunnel_type_socklen_t != yes; then
cat >> confdefs.h <<\EOF
#define socklen_t int
EOF
 
fi
 
echo $ac_n "checking whether INADDR_NONE is defined""... $ac_c" 1>&6
echo "configure:1804: checking whether INADDR_NONE is defined" >&5
if eval "test \"`echo '$''{'ac_cv_httptunnel_define_inaddr_none'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 1810 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <netinet/in.h>
int main() {
return INADDR_NONE;
; return 0; }
EOF
if { (eval echo configure:1818: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_httptunnel_define_inaddr_none=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_httptunnel_define_inaddr_none=no
fi
rm -f conftest*
 
fi
 
echo "$ac_t""$ac_cv_httptunnel_define_inaddr_none" 1>&6
if test $ac_cv_httptunnel_define_inaddr_none != yes; then
cat >> confdefs.h <<\EOF
#define INADDR_NONE 0xffffffff
EOF
 
fi
 
echo $ac_n "checking size of char""... $ac_c" 1>&6
echo "configure:1840: checking size of char" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_char=1
else
cat > conftest.$ac_ext <<EOF
#line 1848 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
{
FILE *f=fopen("conftestval", "w");
if (!f) exit(1);
fprintf(f, "%d\n", sizeof(char));
exit(0);
}
EOF
if { (eval echo configure:1859: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_char=`cat conftestval`
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
ac_cv_sizeof_char=0
fi
rm -fr conftest*
fi
 
fi
echo "$ac_t""$ac_cv_sizeof_char" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_CHAR $ac_cv_sizeof_char
EOF
 
 
echo $ac_n "checking size of short""... $ac_c" 1>&6
echo "configure:1879: checking size of short" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_short=2
else
cat > conftest.$ac_ext <<EOF
#line 1887 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
{
FILE *f=fopen("conftestval", "w");
if (!f) exit(1);
fprintf(f, "%d\n", sizeof(short));
exit(0);
}
EOF
if { (eval echo configure:1898: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_short=`cat conftestval`
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
ac_cv_sizeof_short=0
fi
rm -fr conftest*
fi
 
fi
echo "$ac_t""$ac_cv_sizeof_short" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_SHORT $ac_cv_sizeof_short
EOF
 
 
echo $ac_n "checking size of int""... $ac_c" 1>&6
echo "configure:1918: checking size of int" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_int=4
else
cat > conftest.$ac_ext <<EOF
#line 1926 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
{
FILE *f=fopen("conftestval", "w");
if (!f) exit(1);
fprintf(f, "%d\n", sizeof(int));
exit(0);
}
EOF
if { (eval echo configure:1937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_int=`cat conftestval`
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
ac_cv_sizeof_int=0
fi
rm -fr conftest*
fi
 
fi
echo "$ac_t""$ac_cv_sizeof_int" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_INT $ac_cv_sizeof_int
EOF
 
 
echo $ac_n "checking size of long""... $ac_c" 1>&6
echo "configure:1957: checking size of long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_long=4
else
cat > conftest.$ac_ext <<EOF
#line 1965 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
{
FILE *f=fopen("conftestval", "w");
if (!f) exit(1);
fprintf(f, "%d\n", sizeof(long));
exit(0);
}
EOF
if { (eval echo configure:1976: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_long=`cat conftestval`
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
ac_cv_sizeof_long=0
fi
rm -fr conftest*
fi
 
fi
echo "$ac_t""$ac_cv_sizeof_long" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_LONG $ac_cv_sizeof_long
EOF
 
 
echo $ac_n "checking size of long long""... $ac_c" 1>&6
echo "configure:1996: checking size of long long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_sizeof_long_long=8
else
cat > conftest.$ac_ext <<EOF
#line 2004 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
{
FILE *f=fopen("conftestval", "w");
if (!f) exit(1);
fprintf(f, "%d\n", sizeof(long long));
exit(0);
}
EOF
if { (eval echo configure:2015: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_long_long=`cat conftestval`
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
ac_cv_sizeof_long_long=0
fi
rm -fr conftest*
fi
 
fi
echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
cat >> confdefs.h <<EOF
#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
EOF
 
 
 
echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
echo "configure:2036: checking for 8-bit clean memcmp" >&5
if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
ac_cv_func_memcmp_clean=no
else
cat > conftest.$ac_ext <<EOF
#line 2044 "configure"
#include "confdefs.h"
 
main()
{
char c0 = 0x40, c1 = 0x80, c2 = 0x81;
exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
}
 
EOF
if { (eval echo configure:2054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_memcmp_clean=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
ac_cv_func_memcmp_clean=no
fi
rm -fr conftest*
fi
 
fi
 
echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
 
echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
echo "configure:2072: checking return type of signal handlers" >&5
if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2077 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
#ifdef signal
#undef signal
#endif
#ifdef __cplusplus
extern "C" void (*signal (int, void (*)(int)))(int);
#else
void (*signal ()) ();
#endif
 
int main() {
int i;
; return 0; }
EOF
if { (eval echo configure:2094: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
ac_cv_type_signal=int
fi
rm -f conftest*
fi
 
echo "$ac_t""$ac_cv_type_signal" 1>&6
cat >> confdefs.h <<EOF
#define RETSIGTYPE $ac_cv_type_signal
EOF
 
 
echo $ac_n "checking for vprintf""... $ac_c" 1>&6
echo "configure:2113: checking for vprintf" >&5
if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2118 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char vprintf();
 
int main() {
 
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_vprintf) || defined (__stub___vprintf)
choke me
#else
vprintf();
#endif
 
; return 0; }
EOF
if { (eval echo configure:2141: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_vprintf=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_vprintf=no"
fi
rm -f conftest*
fi
 
if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
#define HAVE_VPRINTF 1
EOF
 
else
echo "$ac_t""no" 1>&6
fi
 
if test "$ac_cv_func_vprintf" != yes; then
echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
echo "configure:2165: checking for _doprnt" >&5
if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2170 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char _doprnt();
 
int main() {
 
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub__doprnt) || defined (__stub____doprnt)
choke me
#else
_doprnt();
#endif
 
; return 0; }
EOF
if { (eval echo configure:2193: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func__doprnt=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func__doprnt=no"
fi
rm -f conftest*
fi
 
if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
#define HAVE_DOPRNT 1
EOF
 
else
echo "$ac_t""no" 1>&6
fi
 
fi
 
for ac_func in socket strdup strerror daemon vsyslog
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2220: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2225 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func();
 
int main() {
 
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
$ac_func();
#endif
 
; return 0; }
EOF
if { (eval echo configure:2248: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
fi
 
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
cat >> confdefs.h <<EOF
#define $ac_tr_func 1
EOF
else
echo "$ac_t""no" 1>&6
fi
done
 
for ac_func in poll select endprotoent vsnprintf syslog
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:2275: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
#line 2280 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func();
 
int main() {
 
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
$ac_func();
#endif
 
; return 0; }
EOF
if { (eval echo configure:2303: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
fi
 
if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
echo "$ac_t""yes" 1>&6
ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
cat >> confdefs.h <<EOF
#define $ac_tr_func 1
EOF
else
echo "$ac_t""no" 1>&6
fi
done
 
 
trap '' 1 2 15
cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs. It is not useful on other systems.
# If it contains results you don't want to keep, you may remove or edit it.
#
# By default, configure uses ./config.cache as the cache file,
# creating it if it does not exist already. You can give configure
# the --cache-file=FILE option to use a different cache file; that is
# what configure does when it calls configure scripts in
# subdirectories, so they share the cache.
# Giving --cache-file=/dev/null disables caching, for debugging configure.
# config.status only pays attention to the cache file if you give it the
# --recheck option to rerun configure.
#
EOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
case `(ac_space=' '; set | grep ac_space) 2>&1` in
*ac_space=\ *)
# `set' does not quote correctly, so add quotes (double-quote substitution
# turns \\\\ into \\, and sed turns \\ into \).
sed -n \
-e "s/'/'\\\\''/g" \
-e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
;;
*)
# `set' quotes correctly as required by POSIX, so do not add quotes.
sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
;;
esac >> confcache
if cmp -s $cache_file confcache; then
:
else
if test -w $cache_file; then
echo "updating cache $cache_file"
cat confcache > $cache_file
else
echo "not updating unwritable cache $cache_file"
fi
fi
rm -f confcache
 
trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
 
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 
# Any assignment to VPATH causes Sun make to only execute
# the first set of double-colon rules, so remove it if not needed.
# If there is a colon in the path, we need to keep it.
if test "x$srcdir" = x.; then
ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
fi
 
trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
 
DEFS=-DHAVE_CONFIG_H
 
# Without the "./", some shells look in PATH for config.status.
: ${CONFIG_STATUS=./config.status}
 
echo creating $CONFIG_STATUS
rm -f $CONFIG_STATUS
cat > $CONFIG_STATUS <<EOF
#! /bin/sh
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
#
# $0 $ac_configure_args
#
# Compiler output produced by configure, useful for debugging
# configure, is in ./config.log if it exists.
 
ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
for ac_option
do
case "\$ac_option" in
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
echo "$CONFIG_STATUS generated by autoconf version 2.13"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
*) echo "\$ac_cs_usage"; exit 1 ;;
esac
done
 
ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
 
trap 'rm -fr `echo "Makefile port/Makefile port/sys/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
 
# Protect against being on the right side of a sed subst in config.status.
sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
s%@exec_prefix@%$exec_prefix%g
s%@prefix@%$prefix%g
s%@program_transform_name@%$program_transform_name%g
s%@bindir@%$bindir%g
s%@sbindir@%$sbindir%g
s%@libexecdir@%$libexecdir%g
s%@datadir@%$datadir%g
s%@sysconfdir@%$sysconfdir%g
s%@sharedstatedir@%$sharedstatedir%g
s%@localstatedir@%$localstatedir%g
s%@libdir@%$libdir%g
s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@PACKAGE@%$PACKAGE%g
s%@VERSION@%$VERSION%g
s%@ACLOCAL@%$ACLOCAL%g
s%@AUTOCONF@%$AUTOCONF%g
s%@AUTOMAKE@%$AUTOMAKE%g
s%@AUTOHEADER@%$AUTOHEADER%g
s%@MAKEINFO@%$MAKEINFO%g
s%@SET_MAKE@%$SET_MAKE%g
s%@SRCDIR_TRUE@%$SRCDIR_TRUE%g
s%@SRCDIR_FALSE@%$SRCDIR_FALSE%g
s%@AWK@%$AWK%g
s%@CC@%$CC%g
s%@LN_S@%$LN_S%g
s%@RANLIB@%$RANLIB%g
s%@CPP@%$CPP%g
s%@LIBOBJS@%$LIBOBJS%g
 
CEOF
EOF
 
cat >> $CONFIG_STATUS <<\EOF
 
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=""
while $ac_more_lines; do
if test $ac_beg -gt 1; then
sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
else
sed "${ac_end}q" conftest.subs > conftest.s$ac_file
fi
if test ! -s conftest.s$ac_file; then
ac_more_lines=false
rm -f conftest.s$ac_file
else
if test -z "$ac_sed_cmds"; then
ac_sed_cmds="sed -f conftest.s$ac_file"
else
ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
fi
ac_file=`expr $ac_file + 1`
ac_beg=$ac_end
ac_end=`expr $ac_end + $ac_max_sed_cmds`
fi
done
if test -z "$ac_sed_cmds"; then
ac_sed_cmds=cat
fi
EOF
 
cat >> $CONFIG_STATUS <<EOF
 
CONFIG_FILES=\${CONFIG_FILES-"Makefile port/Makefile port/sys/Makefile"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
*:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
 
# Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
 
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
# The file is in a subdirectory.
test ! -d "$ac_dir" && mkdir "$ac_dir"
ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
# A "../" for each directory in $ac_dir_suffix.
ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
else
ac_dir_suffix= ac_dots=
fi
 
case "$ac_given_srcdir" in
.) srcdir=.
if test -z "$ac_dots"; then top_srcdir=.
else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
/*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
*) # Relative path.
srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
top_srcdir="$ac_dots$ac_given_srcdir" ;;
esac
 
case "$ac_given_INSTALL" in
[/$]*) INSTALL="$ac_given_INSTALL" ;;
*) INSTALL="$ac_dots$ac_given_INSTALL" ;;
esac
 
echo creating "$ac_file"
rm -f "$ac_file"
configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
case "$ac_file" in
*Makefile*) ac_comsub="1i\\
# $configure_input" ;;
*) ac_comsub= ;;
esac
 
ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
s%@INSTALL@%$INSTALL%g
" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
rm -f conftest.s*
 
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
ac_dC='\3'
ac_dD='%g'
# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_uB='\([ ]\)%\1#\2define\3'
ac_uC=' '
ac_uD='\4%g'
# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_eB='$%\1#\2define\3'
ac_eC=' '
ac_eD='%g'
 
if test "${CONFIG_HEADERS+set}" != set; then
EOF
cat >> $CONFIG_STATUS <<EOF
CONFIG_HEADERS="config.h"
EOF
cat >> $CONFIG_STATUS <<\EOF
fi
for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case "$ac_file" in
*:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
*) ac_file_in="${ac_file}.in" ;;
esac
 
echo creating $ac_file
 
rm -f conftest.frag conftest.in conftest.out
ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
cat $ac_file_inputs > conftest.in
 
EOF
 
# Transform confdefs.h into a sed script conftest.vals that substitutes
# the proper values into config.h.in to produce config.h. And first:
# Protect against being on the right side of a sed subst in config.status.
# Protect against being in an unquoted here document in config.status.
rm -f conftest.vals
cat > conftest.hdr <<\EOF
s/[\\&%]/\\&/g
s%[\\$`]%\\&%g
s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
s%ac_d%ac_u%gp
s%ac_u%ac_e%gp
EOF
sed -n -f conftest.hdr confdefs.h > conftest.vals
rm -f conftest.hdr
 
# This sed command replaces #undef with comments. This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
cat >> conftest.vals <<\EOF
s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
EOF
 
# Break up conftest.vals because some shells have a limit on
# the size of here documents, and old seds have small limits too.
 
rm -f conftest.tail
while :
do
ac_lines=`grep -c . conftest.vals`
# grep -c gives empty output for an empty file on some AIX systems.
if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
# Write a limited-size here document to conftest.frag.
echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
echo 'CEOF
sed -f conftest.frag conftest.in > conftest.out
rm -f conftest.in
mv conftest.out conftest.in
' >> $CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
rm -f conftest.vals
mv conftest.tail conftest.vals
done
rm -f conftest.vals
 
cat >> $CONFIG_STATUS <<\EOF
rm -f conftest.frag conftest.h
echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
cat conftest.in >> conftest.h
rm -f conftest.in
if cmp -s $ac_file conftest.h 2>/dev/null; then
echo "$ac_file is unchanged"
rm -f conftest.h
else
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
# The file is in a subdirectory.
test ! -d "$ac_dir" && mkdir "$ac_dir"
fi
rm -f $ac_file
mv conftest.h $ac_file
fi
fi; done
 
EOF
cat >> $CONFIG_STATUS <<EOF
 
 
EOF
cat >> $CONFIG_STATUS <<\EOF
test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
 
exit 0
EOF
chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
 
New file
/httptunnel/Makefile.in
@@ -0,0 +1,511 @@
# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
 
 
SHELL = @SHELL@
 
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
 
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
 
DESTDIR =
 
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
 
top_builddir = .
 
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
 
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
 
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
AWK = @AWK@
CC = @CC@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
VERSION = @VERSION@
 
SUBDIRS = port
 
bin_PROGRAMS = htc hts
man_MANS = hts.1 htc.1
@SRCDIR_TRUE@CPPFLAGS = -I$(VPATH)/port
@SRCDIR_FALSE@CPPFLAGS = -Iport
 
htc_SOURCES = htc.c common.c tunnel.c http.c base64.c
htc_LDADD = -Lport -lport
hts_SOURCES = hts.c common.c tunnel.c http.c
hts_LDADD = -Lport -lport
 
noinst_HEADERS = common.h tunnel.h http.h base64.h
 
EXTRA_DIST = TODO HACKING DISCLAIMER doc/rfc1945.txt doc/rfc2068.txt FAQ doc/rfc2045.txt hts.1 htc.1 debian/changelog debian/control debian/copyright debian/dirs debian/docs debian/rules debian/prerm debian/postinst
 
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
PROGRAMS = $(bin_PROGRAMS)
 
 
DEFS = @DEFS@ -I. -I$(srcdir) -I.
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
htc_OBJECTS = htc.o common.o tunnel.o http.o base64.o
htc_DEPENDENCIES =
htc_LDFLAGS =
hts_OBJECTS = hts.o common.o tunnel.o http.o
hts_DEPENDENCIES =
hts_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
man1dir = $(mandir)/man1
MANS = $(man_MANS)
 
NROFF = nroff
HEADERS = $(noinst_HEADERS)
 
DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \
Makefile.am Makefile.in NEWS TODO acconfig.h acinclude.m4 aclocal.m4 \
config.h.in configure configure.in install-sh missing mkinstalldirs
 
 
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
TAR = tar
GZIP_ENV = --best
SOURCES = $(htc_SOURCES) $(hts_SOURCES)
OBJECTS = $(htc_OBJECTS) $(hts_OBJECTS)
 
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile
 
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
$(ACLOCAL_M4): configure.in acinclude.m4
cd $(srcdir) && $(ACLOCAL)
 
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
 
config.h: stamp-h
@if test ! -f $@; then \
rm -f stamp-h; \
$(MAKE) stamp-h; \
else :; fi
stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES= CONFIG_HEADERS=config.h \
$(SHELL) ./config.status
@echo timestamp > stamp-h 2> /dev/null
$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
@if test ! -f $@; then \
rm -f $(srcdir)/stamp-h.in; \
$(MAKE) $(srcdir)/stamp-h.in; \
else :; fi
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
cd $(top_srcdir) && $(AUTOHEADER)
@echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
 
mostlyclean-hdr:
 
clean-hdr:
 
distclean-hdr:
-rm -f config.h
 
maintainer-clean-hdr:
 
mostlyclean-binPROGRAMS:
 
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
 
distclean-binPROGRAMS:
 
maintainer-clean-binPROGRAMS:
 
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
else :; fi; \
done
 
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
list='$(bin_PROGRAMS)'; for p in $$list; do \
rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
done
 
.c.o:
$(COMPILE) -c $<
 
.s.o:
$(COMPILE) -c $<
 
.S.o:
$(COMPILE) -c $<
 
mostlyclean-compile:
-rm -f *.o core *.core
 
clean-compile:
 
distclean-compile:
-rm -f *.tab.c
 
maintainer-clean-compile:
 
htc: $(htc_OBJECTS) $(htc_DEPENDENCIES)
@rm -f htc
$(LINK) $(htc_LDFLAGS) $(htc_OBJECTS) $(htc_LDADD) $(LIBS)
 
hts: $(hts_OBJECTS) $(hts_DEPENDENCIES)
@rm -f hts
$(LINK) $(hts_LDFLAGS) $(hts_OBJECTS) $(hts_LDADD) $(LIBS)
 
install-man1:
$(mkinstalldirs) $(DESTDIR)$(man1dir)
@list='$(man1_MANS)'; \
l2='$(man_MANS)'; for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
done
 
uninstall-man1:
@list='$(man1_MANS)'; \
l2='$(man_MANS)'; for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
rm -f $(DESTDIR)$(man1dir)/$$inst; \
done
install-man: $(MANS)
@$(NORMAL_INSTALL)
$(MAKE) $(AM_MAKEFLAGS) install-man1
uninstall-man:
@$(NORMAL_UNINSTALL)
$(MAKE) $(AM_MAKEFLAGS) uninstall-man1
 
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
 
@SET_MAKE@
 
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
 
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" = "." && dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
 
tags: TAGS
 
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
 
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
 
mostlyclean-tags:
 
clean-tags:
 
distclean-tags:
-rm -f TAGS ID
 
maintainer-clean-tags:
 
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
 
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
-rm -rf $(distdir)
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
dc_install_base=`cd $(distdir)/=inst && pwd`; \
cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) dist
-rm -rf $(distdir)
@banner="$(distdir).tar.gz is ready for distribution"; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"
dist: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
dist-all: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
distdir: $(DISTFILES)
-rm -rf $(distdir)
mkdir $(distdir)
-chmod 777 $(distdir)
$(mkinstalldirs) $(distdir)/debian $(distdir)/doc
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
fi; \
done
base64.o: base64.c config.h base64.h common.h port/stdio_.h \
port/unistd_.h port/getopt.h port/syslog_.h tunnel.h
common.o: common.c port/netdb_.h config.h port/syslog_.h \
port/sys/poll_.h tunnel.h common.h port/stdio_.h port/unistd_.h \
port/getopt.h
htc.o: htc.c port/unistd_.h config.h port/getopt.h port/sys/poll_.h \
common.h port/stdio_.h port/syslog_.h tunnel.h base64.h
hts.o: hts.c port/unistd_.h config.h port/getopt.h port/sys/poll_.h \
common.h port/stdio_.h port/syslog_.h tunnel.h
http.o: http.c http.h common.h config.h port/stdio_.h port/unistd_.h \
port/getopt.h port/syslog_.h tunnel.h
rw.o: rw.c common.h config.h tunnel.h
tt.o: tt.c common.h config.h tunnel.h
tunnel.o: tunnel.c port/netdb_.h config.h port/sys/poll_.h http.h \
tunnel.h common.h port/stdio_.h port/unistd_.h port/getopt.h \
port/syslog_.h
 
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
all-recursive-am: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
install-exec-am: install-binPROGRAMS
install-exec: install-exec-recursive
 
install-data-am: install-man
install-data: install-data-recursive
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-recursive
uninstall-am: uninstall-binPROGRAMS uninstall-man
uninstall: uninstall-recursive
all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) config.h
all-redirect: all-recursive-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
 
 
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
 
maintainer-clean-generic:
mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS \
mostlyclean-compile mostlyclean-tags \
mostlyclean-generic
 
mostlyclean: mostlyclean-recursive
 
clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-tags \
clean-generic mostlyclean-am
 
clean: clean-recursive
 
distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile \
distclean-tags distclean-generic clean-am
 
distclean: distclean-recursive
-rm -f config.status
 
maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
 
maintainer-clean: maintainer-clean-recursive
-rm -f config.status
 
.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile install-man1 uninstall-man1 install-man \
uninstall-man install-data-recursive uninstall-data-recursive \
install-exec-recursive uninstall-exec-recursive installdirs-recursive \
uninstalldirs-recursive all-recursive check-recursive \
installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
install-exec-am install-exec install-data-am install-data install-am \
install uninstall-am uninstall all-redirect all-am all installdirs-am \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
New file
/httptunnel/debian/changelog
@@ -0,0 +1,63 @@
httptunnel (3.2) unstable; urgency=low
 
* New upstream version.
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Thu, 31 Aug 2000 08:03:42 +0300
 
httptunnel (3.1-1) unstable; urgency=low
 
* New upstream version. (Closes: #67354)
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Wed, 26 Jul 2000 10:59:41 +0300
 
httptunnel (3.0.3-1) unstable; urgency=low
 
* New upstream version.
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Sun, 23 Jul 2000 03:52:55 +0300
 
httptunnel (3.0.2) unstable; urgency=low
 
* New upstream version.
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Wed, 14 Jun 2000 22:49:02 +0300
 
httptunnel (3.0) unstable; urgency=low
 
* A stable release created from the development branch. Upstream
changes from the previous debian packaged version include two
patches, fixing TUN driver compatibility and poll() emulation.
Essentially this is the same version as 2.11-2.
* Cleaned up the build scripts quite a bit.
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Wed, 12 Jan 2000 20:09:04 +0200
 
httptunnel (2.11-2) unstable; urgency=low
 
* New upstream version from CVS
* FHS transition
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Wed, 27 Oct 1999 10:52:18 +0300
 
httptunnel (2.11-1) unstable; urgency=low
 
* New upstream release.
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Tue, 24 Aug 1999 13:28:54 +0300
 
httptunnel (2.10-1) unstable; urgency=low
 
* New upstream release.
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Sat, 14 Aug 1999 00:29:55 +0300
 
httptunnel (2.8-1) unstable; urgency=low
 
* Initial Release.
 
-- Teemu Hukkanen <tjhukkan@iki.fi> Thu, 12 Aug 1999 11:56:17 +0300
 
Local variables:
mode: debian-changelog
add-log-mailing-address: "tjhukkan@iki.fi"
End:
New file
/httptunnel/debian/copyright
@@ -0,0 +1,21 @@
This package was debianized by Teemu Hukkanen <tjhukkan@iki.fi> on
Wed, 28 Jul 1999 16:00:06 +0300.
 
It was downloaded from <ftp://ftp.gnu.org/pub/httptunnel/>
 
Upstream Author(s): Lars Brinkhoff <lars@nocrew.org>
 
Copyright:
httptunnel is licensed under the GNU General Public License.
 
---
httptunnel is free software. See COPYING for terms and conditions.
If you like it, I would appreciate if you sent a post card to:
Lars Brinkhoff
Kopmansgatan 2
411 13 Goteborg
Sweden
---
 
A copy of the GNU General Public License is available on Debian
GNU/Linux systems as /usr/share/common-license/GPL.
New file
/httptunnel/debian/docs
@@ -0,0 +1,8 @@
FAQ
INSTALL
NEWS
README
TODO
DISCLAIMER
AUTHORS
HACKING
New file
/httptunnel/debian/rules
@@ -0,0 +1,87 @@
#!/usr/bin/make -f
#-*- makefile -*-
 
install = install -o root -g root
install_exec = $(install) -m 755 -s
install_dir = $(install) -m 755 -d
install_nonex = $(install) -m 644
install_script = $(install) -m 755
install_zipped = gzip -9vc
install_symlink = ln -s
 
package = httptunnel
rootdir = `pwd`/debian/tmp
docdir = $(rootdir)/usr/share/doc/$(package)
bindir = $(rootdir)/usr/bin
mandir = $(rootdir)/usr/share/man
man1dir = $(mandir)/man1
 
build: debian/build.stamp
debian/build.stamp:
$(checkdir)
CFLAGS="-O2 -g -Wall" CC=gcc ./configure --prefix=/usr \
--mandir=/usr/share/man
$(MAKE)
touch $@
 
clean-build:
$(RM) debian/build*.stamp
-$(MAKE) distclean
 
binary: binary-arch binary-indep
 
binary-indep: debian/binary-indep.stamp
debian/binary-indep.stamp:
touch $@
 
binary-arch: debian/binary-arch.stamp
debian/binary-arch.stamp: build
$(checkdir)
$(RM) -r $(rootdir)
$(install_dir) $(rootdir)
$(install_dir) $(rootdir)/DEBIAN
$(install_dir) $(docdir)
$(install_dir) $(bindir)
$(install_dir) $(man1dir)
$(MAKE) install-strip prefix=`pwd`/debian/tmp/usr mandir=`pwd`/debian/tmp/usr/share/man
# changelogs
$(install_nonex) debian/changelog $(docdir)/changelog.Debian
$(install_nonex) ChangeLog $(docdir)/changelog
# docs
$(install_nonex) FAQ $(docdir)
$(install_nonex) INSTALL $(docdir)
$(install_nonex) NEWS $(docdir)
$(install_nonex) README $(docdir)
$(install_nonex) TODO $(docdir)
$(install_nonex) DISCLAIMER $(docdir)
$(install_nonex) AUTHORS $(docdir)
$(install_nonex) HACKING $(docdir)
gzip -9vfr $(docdir)/
 
gzip -9vfr $(man1dir)/
 
# copyright
$(install_nonex) debian/copyright $(docdir)
# control
$(install_script) debian/prerm $(rootdir)/DEBIAN
$(install_script) debian/postinst $(rootdir)/DEBIAN
 
dpkg-shlibdeps $(bindir)/hts $(bindir)/htc
dpkg-gencontrol -isp
 
chown -R root.root $(rootdir)
chmod -R g-ws $(rootdir)
 
dpkg --build $(rootdir) ..
touch $@
 
define checkdir
test -f htc.c -a -f hts.c -a -f debian/rules
endef
 
clean-binary:
$(RM) debian/binary*.stamp
$(RM) *~
$(RM) -r debian/tmp debian/*~ debian/files debian/substvars
 
clean: clean-build clean-binary
New file
/httptunnel/debian/control
@@ -0,0 +1,14 @@
Source: httptunnel
Section: net
Priority: optional
Maintainer: Teemu Hukkanen <tjhukkan@iki.fi>
Standards-Version: 3.1.0.0
 
Package: httptunnel
Architecture: any
Depends: ${shlibs:Depends}
Description: Tunnels a data stream in HTTP requests.
Creates a bidirectional virtual data stream tunnelled in
HTTP requests. The requests can be sent via a HTTP proxy
if so desired.
 
New file
/httptunnel/debian/dirs
@@ -0,0 +1,3 @@
usr/bin
usr/share/man
usr/share/man/man1
New file
/httptunnel/debian/postinst
@@ -0,0 +1,6 @@
#!/bin/sh
if [ "$1" = "configure" ]; then
if [ -d /usr/doc -a ! -e /usr/doc/httptunnel -a -d /usr/share/doc/httptunnel ]; then
ln -sf ../share/doc/httptunnel /usr/doc/httptunnel
fi
fi
New file
/httptunnel/debian/prerm
@@ -0,0 +1,4 @@
#!/bin/sh
if [ \( "$1" = "upgrade" -o "$1" = "remove" \) -a -L /usr/doc/httptunnel ]; then
rm -f /usr/doc/httptunnel
fi

Property changes:

Name: bugtraq:number
+ true

/httptunnel/debian
New file
/httptunnel/port/poll.c
@@ -0,0 +1,73 @@
/*
port/poll.c
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#include "config.h"
 
#ifndef HAVE_POLL
 
#include <unistd_.h>
#include <sys/poll_.h>
#include <sys/time.h>
#include <sys/types.h>
 
#ifndef HAVE_SELECT
#error "Must have either poll() or select()."
#endif
 
int
poll (struct pollfd *p, int n, int t)
{
struct timeval t2, *t3;
fd_set r, w, e;
int i, m, ret;
 
FD_ZERO (&r);
FD_ZERO (&w);
FD_ZERO (&e);
m = -1;
for (i = 0; i < n; i++)
{
if (p[i].fd < 0)
continue;
if (p[i].events & POLLIN)
FD_SET (p[i].fd, &r);
if (p[i].events & POLLOUT)
FD_SET (p[i].fd, &w);
FD_SET (p[i].fd, &e); /* or something */
if (p[i].fd > m)
m = p[i].fd;
}
 
if (m == -1)
return 0;
 
if (t < 0)
t3 = NULL;
else
{
t2.tv_sec = t / 1000;
t2.tv_usec = 1000 * (t % 1000);
t3 = &t2;
}
 
ret = select (m + 1, &r, &w, &e, t3);
 
if (ret != -1)
for (i = 0; i < n; i++)
{
p[i].revents = 0;
if (FD_ISSET (p[i].fd, &r))
p[i].revents |= POLLIN;
if (FD_ISSET (p[i].fd, &w))
p[i].revents |= POLLOUT;
if (FD_ISSET (p[i].fd, &e))
p[i].revents |= POLLERR; /* or something */
}
 
return ret;
}
 
#endif /* HAVE_POLL */
New file
/httptunnel/port/stdio_.h
@@ -0,0 +1,22 @@
/*
port/stdio_.h
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#ifndef PORT_STDIO_H
#define PORT_STDIO_H
 
#include <stdio.h>
#include <stdarg.h>
#include <sys/types.h>
 
#include "config.h"
 
extern int vsmprintf (char **str, const char *format, va_list ap);
#ifndef HAVE_VSNPRINTF
extern int vsnprintf (char *str, size_t n, const char *format, va_list ap);
extern int snprintf (char *str, size_t n, const char *format, ...);
#endif
 
#endif /* PORT_STDIO_H */
New file
/httptunnel/port/vsyslog.c
@@ -0,0 +1,38 @@
/*
port/vsyslog.c
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#include <stdio_.h>
#include <syslog_.h>
#include <stdarg.h>
 
#include "config.h"
 
#ifndef HAVE_SYSLOG
void
syslog (int level, const char *fmt0, ...)
{
#ifdef HAVE_VSYSLOG
va_list ap;
va_start (ap, fmt0);
vsyslog (level, fmt0, ap);
va_end (ap);
#else
/* This system has neither syslog() nor vsyslog(), so do nothing. */
/* FIXME: this function could open a file and log messages in it. */
#endif
}
#endif
 
#ifndef HAVE_VSYSLOG
void
vsyslog (int level, const char *fmt0, va_list ap)
{
char buffer[512];
 
if (vsnprintf (buffer, sizeof buffer, fmt0, ap) > 0)
syslog (level, buffer);
}
#endif /* HAVE_VSYSLOG */
New file
/httptunnel/port/getopt.h
@@ -0,0 +1,135 @@
/* Declarations for getopt.
Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
 
the C library, however. The master source lives in /gd/gnu/lib.
 
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
 
#ifndef _GETOPT_H
#define _GETOPT_H 1
 
#ifdef __cplusplus
extern "C" {
#endif
 
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
 
extern char *optarg;
 
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
 
On entry to `getopt', zero means this is the first call; initialize.
 
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
 
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
 
extern int optind;
 
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
 
extern int opterr;
 
/* Set to an option character which was unrecognized. */
 
extern int optopt;
 
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
 
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
 
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
 
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
 
struct option
{
#if defined (__STDC__) && __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
 
/* Names for the values of the `has_arg' field of `struct option'. */
 
#define no_argument 0
#define required_argument 1
#define optional_argument 2
 
#if defined (__STDC__) && __STDC__
#ifdef __GNU_LIBRARY__
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt ();
#endif /* __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
 
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt ();
extern int getopt_long ();
extern int getopt_long_only ();
 
extern int _getopt_internal ();
#endif /* __STDC__ */
 
#ifdef __cplusplus
}
#endif
 
#endif /* _GETOPT_H */
New file
/httptunnel/port/Makefile.am
@@ -0,0 +1,6 @@
SUBDIRS = sys
noinst_LIBRARIES = libport.a
libport_a_SOURCES = poll.c daemon.c unistd_.h vsyslog.c syslog_.h \
endprotoent.c getopt.c getopt1.c vsnprintf.c getopt.h \
stdio_.h netdb_.h
 
New file
/httptunnel/port/vsnprintf.c
@@ -0,0 +1,76 @@
/*
port/vsnprintf.c
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#include "config.h"
 
#include <stdio_.h>
#include <stdarg.h>
#include <stdlib.h>
#include <sys/types.h>
 
#ifndef HAVE_VPRINTF
#error "Must have vfprintf() and vsprintf()."
#endif
 
int
vsmprintf (char **s, const char *format, va_list ap)
{
size_t n;
FILE *f;
 
f = fopen ("/dev/null", "w");
if (f == NULL)
return -1;
 
n = vfprintf (f, format, ap);
fclose (f);
 
*s = malloc (n + 1);
if (*s == NULL)
return -1;
 
return vsprintf (*s, format, ap);
}
 
#ifndef HAVE_VSNPRINTF
int
vsnprintf (char *str, size_t n, const char *format, va_list ap)
{
char *s;
int m, r;
 
m = vsmprintf (&s, format, ap);
if (m == -1)
return 0;
 
if (m + 1 > n)
{
m = n - 1;
r = -1;
}
else
{
r = m;
}
 
memcpy (str, s, m);
free (s);
str[m] = 0;
return r;
}
 
int
snprintf (char *s, size_t n, const char *format, ...)
{
va_list ap;
int m;
 
va_start (ap, format);
m = vsnprintf (s, n, format, ap);
va_end (ap);
return m;
}
#endif /* HAVE_VSNPRINTF */
New file
/httptunnel/port/unistd_.h
@@ -0,0 +1,18 @@
/*
port/unistd_.h
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#ifndef PORT_UNISTD_H
#define PORT_UNISTD_H
 
#include "config.h"
 
#ifndef HAVE_DAEMON
extern int daemon (int, int);
#endif
 
#include <unistd.h>
 
#endif /* PORT_UNISTD_H */
New file
/httptunnel/port/sys/Makefile.am
@@ -0,0 +1 @@
noinst_HEADERS = poll_.h
New file
/httptunnel/port/sys/poll_.h
@@ -0,0 +1,33 @@
/*
port/sys/poll_.h
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#ifndef PORT_SYS_POLL_H
#define PORT_SYS_POLL_H
 
#include "config.h"
 
#ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
#else
 
#define POLLIN 0x01
#define POLLOUT 0x02
#define POLLERR 0x10
#define POLLHUP 0x20
#define POLLNVAL 0x40
 
struct pollfd
{
int fd;
int events;
int revents;
};
 
extern int poll (struct pollfd *p, int n, int timeout);
 
#endif /* !HAVE_SYS_POLL_H */
 
#endif /* PORT_SYS_POLL_H */
New file
/httptunnel/port/sys/Makefile.in
@@ -0,0 +1,200 @@
# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
 
 
SHELL = @SHELL@
 
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
 
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
 
DESTDIR =
 
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
 
top_builddir = ../..
 
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
 
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
 
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
AWK = @AWK@
CC = @CC@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
VERSION = @VERSION@
 
noinst_HEADERS = poll_.h
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h
CONFIG_CLEAN_FILES =
HEADERS = $(noinst_HEADERS)
 
DIST_COMMON = Makefile.am Makefile.in
 
 
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
TAR = tar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps port/sys/Makefile
 
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
 
tags: TAGS
 
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
 
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
 
mostlyclean-tags:
 
clean-tags:
 
distclean-tags:
-rm -f TAGS ID
 
maintainer-clean-tags:
 
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 
subdir = port/sys
 
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
 
install-data-am:
install-data: install-data-am
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile $(HEADERS)
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
 
 
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
 
maintainer-clean-generic:
mostlyclean-am: mostlyclean-tags mostlyclean-generic
 
mostlyclean: mostlyclean-am
 
clean-am: clean-tags clean-generic mostlyclean-am
 
clean: clean-am
 
distclean-am: distclean-tags distclean-generic clean-am
 
distclean: distclean-am
 
maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
 
maintainer-clean: maintainer-clean-am
 
.PHONY: tags mostlyclean-tags distclean-tags clean-tags \
maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
 
 
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

Property changes:

Name: bugtraq:number
+ true

/httptunnel/port/sys
New file
/httptunnel/port/netdb_.h
@@ -0,0 +1,18 @@
/*
port/Netdb.h
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#ifndef PORT_NETDB_H
#define PORT_NETDB_H
 
#include <netdb.h>
 
#include "config.h"
 
#ifndef HAVE_ENDPROTOENT
void endprotoent (void);
#endif
 
#endif /* PORT_NETDB_H */
New file
/httptunnel/port/Makefile.in
@@ -0,0 +1,344 @@
# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
 
 
SHELL = @SHELL@
 
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
 
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
 
DESTDIR =
 
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
 
top_builddir = ..
 
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
 
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
 
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
AWK = @AWK@
CC = @CC@
LN_S = @LN_S@
MAKEINFO = @MAKEINFO@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
VERSION = @VERSION@
 
SUBDIRS = sys
noinst_LIBRARIES = libport.a
libport_a_SOURCES = poll.c daemon.c unistd_.h vsyslog.c syslog_.h endprotoent.c getopt.c getopt1.c vsnprintf.c getopt.h stdio_.h netdb_.h
 
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
 
 
DEFS = @DEFS@ -I. -I$(srcdir) -I..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libport_a_LIBADD =
libport_a_OBJECTS = poll.o daemon.o vsyslog.o endprotoent.o getopt.o \
getopt1.o vsnprintf.o
AR = ar
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = Makefile.am Makefile.in
 
 
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
TAR = tar
GZIP_ENV = --best
SOURCES = $(libport_a_SOURCES)
OBJECTS = $(libport_a_OBJECTS)
 
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps port/Makefile
 
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
 
mostlyclean-noinstLIBRARIES:
 
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
 
distclean-noinstLIBRARIES:
 
maintainer-clean-noinstLIBRARIES:
 
.c.o:
$(COMPILE) -c $<
 
.s.o:
$(COMPILE) -c $<
 
.S.o:
$(COMPILE) -c $<
 
mostlyclean-compile:
-rm -f *.o core *.core
 
clean-compile:
 
distclean-compile:
-rm -f *.tab.c
 
maintainer-clean-compile:
 
libport.a: $(libport_a_OBJECTS) $(libport_a_DEPENDENCIES)
-rm -f libport.a
$(AR) cru libport.a $(libport_a_OBJECTS) $(libport_a_LIBADD)
$(RANLIB) libport.a
 
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
 
@SET_MAKE@
 
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
 
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" = "." && dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
 
tags: TAGS
 
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
 
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
 
mostlyclean-tags:
 
clean-tags:
 
distclean-tags:
-rm -f TAGS ID
 
maintainer-clean-tags:
 
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
 
subdir = port
 
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
fi; \
done
daemon.o: daemon.c ../config.h
endprotoent.o: endprotoent.c netdb_.h ../config.h
getopt.o: getopt.c ../config.h stdio_.h
getopt1.o: getopt1.c ../config.h getopt.h stdio_.h
poll.o: poll.c ../config.h
vsnprintf.o: vsnprintf.c ../config.h stdio_.h
vsyslog.o: vsyslog.c stdio_.h ../config.h syslog_.h
 
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
install-exec-am:
install-exec: install-exec-recursive
 
install-data-am:
install-data: install-data-recursive
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-recursive
uninstall-am:
uninstall: uninstall-recursive
all-am: Makefile $(LIBRARIES)
all-redirect: all-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs: installdirs-recursive
installdirs-am:
 
 
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
 
maintainer-clean-generic:
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-tags mostlyclean-generic
 
mostlyclean: mostlyclean-recursive
 
clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
mostlyclean-am
 
clean: clean-recursive
 
distclean-am: distclean-noinstLIBRARIES distclean-compile \
distclean-tags distclean-generic clean-am
 
distclean: distclean-recursive
 
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-tags \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
 
maintainer-clean: maintainer-clean-recursive
 
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile install-data-recursive \
uninstall-data-recursive install-exec-recursive \
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
all-recursive check-recursive installcheck-recursive info-recursive \
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs-am \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
New file
/httptunnel/port/endprotoent.c
@@ -0,0 +1,17 @@
/*
port/endprotoent.c
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#include <netdb_.h>
 
#include "config.h"
 
#ifndef HAVE_ENDPROTOENT
void
endprotoent (void)
{
/* do nothing */
}
#endif
New file
/httptunnel/port/getopt.c
@@ -0,0 +1,1058 @@
/* Getopt for GNU.
NOTE: getopt is now part of the C library, so if you don't know what
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
before changing it!
 
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
Free Software Foundation, Inc.
 
the C library, however. The master source lives in /gd/gnu/lib.
 
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
Ditto for AIX 3.2 and <stdlib.h>. */
#ifndef _NO_PROTO
#define _NO_PROTO
#endif
 
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
 
#if !defined (__STDC__) || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
 
#include <stdio_.h>
#include <string.h>
 
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
 
#define GETOPT_INTERFACE_VERSION 2
#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
 
#ifndef ELIDE_CODE
 
 
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
/* Don't include stdlib.h for non-GNU C libraries because some of them
contain conflicting prototypes for getopt. */
#include <stdlib.h>
#include <unistd_.h>
#endif /* GNU C library. */
 
#ifdef VMS
#include <unixlib.h>
#if HAVE_STRING_H - 0
#include <string.h>
#endif
#endif
 
#if defined (WIN32) && !defined (__CYGWIN32__)
/* It's not Unix, really. See? Capital letters. */
#include <windows.h>
#define getpid() GetCurrentProcessId()
#endif
 
#ifndef _
/* This is for other GNU distributions with internationalized messages.
When compiling libc, the _ macro is predefined. */
#ifdef HAVE_LIBINTL_H
# include <libintl.h>
# define _(msgid) gettext (msgid)
#else
# define _(msgid) (msgid)
#endif
#endif
 
/* This version of `getopt' appears to the caller like standard Unix `getopt'
but it behaves differently for the user, since it allows the user
to intersperse the options with the other arguments.
 
As `getopt' works, it permutes the elements of ARGV so that,
when it is done, all the options precede everything else. Thus
all application programs are extended to handle flexible argument order.
 
Setting the environment variable POSIXLY_CORRECT disables permutation.
Then the behavior is completely standard.
 
GNU application programs can use a third alternative mode in which
they can distinguish the relative order of options and other arguments. */
 
#include "getopt.h"
 
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
 
char *optarg = NULL;
 
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
 
On entry to `getopt', zero means this is the first call; initialize.
 
When `getopt' returns -1, this is the index of the first of the
non-option elements that the caller should itself scan.
 
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
 
/* 1003.2 says this must be 1 before any call. */
int optind = 1;
 
/* Formerly, initialization of getopt depended on optind==0, which
causes problems with re-calling getopt as programs generally don't
know that. */
 
int __getopt_initialized = 0;
 
/* The next char to be scanned in the option-element
in which the last option character we returned was found.
This allows us to pick up the scan where we left off.
 
If this is zero, or a null string, it means resume the scan
by advancing to the next ARGV-element. */
 
static char *nextchar;
 
/* Callers store zero here to inhibit the error message
for unrecognized options. */
 
int opterr = 1;
 
/* Set to an option character which was unrecognized.
This must be initialized on some systems to avoid linking in the
system's own getopt implementation. */
 
int optopt = '?';
 
/* Describe how to deal with options that follow non-option ARGV-elements.
 
If the caller did not specify anything,
the default is REQUIRE_ORDER if the environment variable
POSIXLY_CORRECT is defined, PERMUTE otherwise.
 
REQUIRE_ORDER means don't recognize them as options;
stop option processing when the first non-option is seen.
This is what Unix does.
This mode of operation is selected by either setting the environment
variable POSIXLY_CORRECT, or using `+' as the first character
of the list of option characters.
 
PERMUTE is the default. We permute the contents of ARGV as we scan,
so that eventually all the non-options are at the end. This allows options
to be given in any order, even with programs that were not written to
expect this.
 
RETURN_IN_ORDER is an option available to programs that were written
to expect options and other ARGV-elements in any order and that care about
the ordering of the two. We describe each non-option ARGV-element
as if it were the argument of an option with character code 1.
Using `-' as the first character of the list of option characters
selects this mode of operation.
 
The special argument `--' forces an end of option-scanning regardless
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
`--' can cause `getopt' to return -1 with `optind' != ARGC. */
 
static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
 
/* Value of POSIXLY_CORRECT environment variable. */
static char *posixly_correct;
#ifdef __GNU_LIBRARY__
/* We want to avoid inclusion of string.h with non-GNU libraries
because there are many ways it can cause trouble.
On some systems, it contains special magic macros that don't work
in GCC. */
#include <string.h>
#define my_index strchr
#else
 
/* Avoid depending on library functions or files
whose names are inconsistent. */
 
char *getenv ();
 
static char *
my_index (str, chr)
const char *str;
int chr;
{
while (*str)
{
if (*str == chr)
return (char *) str;
str++;
}
return 0;
}
 
/* If using GCC, we can safely declare strlen this way.
If not using GCC, it is ok not to declare it. */
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
#if !defined (__STDC__) || !__STDC__
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int strlen (const char *);
#endif /* not __STDC__ */
#endif /* __GNUC__ */
 
#endif /* not __GNU_LIBRARY__ */
/* Handle permutation of arguments. */
 
/* Describe the part of ARGV that contains non-options that have
been skipped. `first_nonopt' is the index in ARGV of the first of them;
`last_nonopt' is the index after the last of them. */
 
static int first_nonopt;
static int last_nonopt;
 
#ifdef _LIBC
/* Bash 2.0 gives us an environment variable containing flags
indicating ARGV elements that should not be considered arguments. */
 
/* Defined in getopt_init.c */
extern char *__getopt_nonoption_flags;
 
static int nonoption_flags_max_len;
static int nonoption_flags_len;
 
static int original_argc;
static char *const *original_argv;
 
extern pid_t __libc_pid;
 
/* Make sure the environment variable bash 2.0 puts in the environment
is valid for the getopt call we must make sure that the ARGV passed
to getopt is that one passed to the process. */
static void
__attribute__ ((unused))
store_args_and_env (int argc, char *const *argv)
{
/* XXX This is no good solution. We should rather copy the args so
that we can compare them later. But we must not use malloc(3). */
original_argc = argc;
original_argv = argv;
}
text_set_element (__libc_subinit, store_args_and_env);
 
# define SWAP_FLAGS(ch1, ch2) \
if (nonoption_flags_len > 0) \
{ \
char __tmp = __getopt_nonoption_flags[ch1]; \
__getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
__getopt_nonoption_flags[ch2] = __tmp; \
}
#else /* !_LIBC */
# define SWAP_FLAGS(ch1, ch2)
#endif /* _LIBC */
 
/* Exchange two adjacent subsequences of ARGV.
One subsequence is elements [first_nonopt,last_nonopt)
which contains all the non-options that have been skipped so far.
The other is elements [last_nonopt,optind), which contains all
the options processed since those non-options were skipped.
 
`first_nonopt' and `last_nonopt' are relocated so that they describe
the new indices of the non-options in ARGV after they are moved. */
 
#if defined (__STDC__) && __STDC__
static void exchange (char **);
#endif
 
static void
exchange (argv)
char **argv;
{
int bottom = first_nonopt;
int middle = last_nonopt;
int top = optind;
char *tem;
 
/* Exchange the shorter segment with the far end of the longer segment.
That puts the shorter segment into the right place.
It leaves the longer segment in the right place overall,
but it consists of two parts that need to be swapped next. */
 
#ifdef _LIBC
/* First make sure the handling of the `__getopt_nonoption_flags'
string can work normally. Our top argument must be in the range
of the string. */
if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
{
/* We must extend the array. The user plays games with us and
presents new arguments. */
char *new_str = malloc (top + 1);
if (new_str == NULL)
nonoption_flags_len = nonoption_flags_max_len = 0;
else
{
memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
memset (&new_str[nonoption_flags_max_len], '\0',
top + 1 - nonoption_flags_max_len);
nonoption_flags_max_len = top + 1;
__getopt_nonoption_flags = new_str;
}
}
#endif
 
while (top > middle && middle > bottom)
{
if (top - middle > middle - bottom)
{
/* Bottom segment is the short one. */
int len = middle - bottom;
register int i;
 
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[top - (middle - bottom) + i];
argv[top - (middle - bottom) + i] = tem;
SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
}
/* Exclude the moved bottom segment from further swapping. */
top -= len;
}
else
{
/* Top segment is the short one. */
int len = top - middle;
register int i;
 
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
{
tem = argv[bottom + i];
argv[bottom + i] = argv[middle + i];
argv[middle + i] = tem;
SWAP_FLAGS (bottom + i, middle + i);
}
/* Exclude the moved top segment from further swapping. */
bottom += len;
}
}
 
/* Update records for the slots the non-options now occupy. */
 
first_nonopt += (optind - last_nonopt);
last_nonopt = optind;
}
 
/* Initialize the internal data when the first call is made. */
 
#if defined (__STDC__) && __STDC__
static const char *_getopt_initialize (int, char *const *, const char *);
#endif
static const char *
_getopt_initialize (argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
is the program name); the sequence of previously skipped
non-option ARGV-elements is empty. */
 
first_nonopt = last_nonopt = optind;
 
nextchar = NULL;
 
posixly_correct = getenv ("POSIXLY_CORRECT");
 
/* Determine how to handle the ordering of options and nonoptions. */
 
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (posixly_correct != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
 
#ifdef _LIBC
if (posixly_correct == NULL
&& argc == original_argc && argv == original_argv)
{
if (nonoption_flags_max_len == 0)
{
if (__getopt_nonoption_flags == NULL
|| __getopt_nonoption_flags[0] == '\0')
nonoption_flags_max_len = -1;
else
{
const char *orig_str = __getopt_nonoption_flags;
int len = nonoption_flags_max_len = strlen (orig_str);
if (nonoption_flags_max_len < argc)
nonoption_flags_max_len = argc;
__getopt_nonoption_flags =
(char *) malloc (nonoption_flags_max_len);
if (__getopt_nonoption_flags == NULL)
nonoption_flags_max_len = -1;
else
{
memcpy (__getopt_nonoption_flags, orig_str, len);
memset (&__getopt_nonoption_flags[len], '\0',
nonoption_flags_max_len - len);
}
}
}
nonoption_flags_len = nonoption_flags_max_len;
}
else
nonoption_flags_len = 0;
#endif
 
return optstring;
}
/* Scan elements of ARGV (whose length is ARGC) for option characters
given in OPTSTRING.
 
If an element of ARGV starts with '-', and is not exactly "-" or "--",
then it is an option element. The characters of this element
(aside from the initial '-') are option characters. If `getopt'
is called repeatedly, it returns successively each of the option characters
from each of the option elements.
 
If `getopt' finds another option character, it returns that character,
updating `optind' and `nextchar' so that the next call to `getopt' can
resume the scan with the following option character or ARGV-element.
 
If there are no more option characters, `getopt' returns -1.
Then `optind' is the index in ARGV of the first ARGV-element
that is not an option. (The ARGV-elements have been permuted
so that those that are not options now come last.)
 
OPTSTRING is a string containing the legitimate option characters.
If an option character is seen that is not listed in OPTSTRING,
return '?' after printing an error message. If you set `opterr' to
zero, the error message is suppressed but we still return '?'.
 
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
so the following text in the same ARGV-element, or the text of the following
ARGV-element, is returned in `optarg'. Two colons mean an option that
wants an optional arg; if there is text in the current ARGV-element,
it is returned in `optarg', otherwise `optarg' is set to zero.
 
If OPTSTRING starts with `-' or `+', it requests different methods of
handling the non-option ARGV-elements.
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
 
Long-named options begin with `--' instead of `-'.
Their names may be abbreviated as long as the abbreviation is unique
or is an exact match for some defined option. If they have an
argument, it follows the option name in the same ARGV-element, separated
from the option name by a `=', or else the in next ARGV-element.
When `getopt' finds a long-named option, it returns 0 if that option's
`flag' field is nonzero, the value of the option's `val' field
if the `flag' field is zero.
 
The elements of ARGV aren't really const, because we permute them.
But we pretend they're const in the prototype to be compatible
with other systems.
 
LONGOPTS is a vector of `struct option' terminated by an
element containing a name which is zero.
 
LONGIND returns the index in LONGOPT of the long-named option found.
It is only valid when a long-named option has been found by the most
recent call.
 
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
long-named options. */
 
int
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
int argc;
char *const *argv;
const char *optstring;
const struct option *longopts;
int *longind;
int long_only;
{
optarg = NULL;
 
if (optind == 0 || !__getopt_initialized)
{
if (optind == 0)
optind = 1; /* Don't scan ARGV[0], the program name. */
optstring = _getopt_initialize (argc, argv, optstring);
__getopt_initialized = 1;
}
 
/* Test whether ARGV[optind] points to a non-option argument.
Either it does not have option syntax, or there is an environment flag
from the shell indicating it is not an option. The later information
is only used when the used in the GNU libc. */
#ifdef _LIBC
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
|| (optind < nonoption_flags_len \
&& __getopt_nonoption_flags[optind] == '1'))
#else
#define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
#endif
 
if (nextchar == NULL || *nextchar == '\0')
{
/* Advance to the next ARGV-element. */
 
/* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
moved back by the user (who may also have changed the arguments). */
if (last_nonopt > optind)
last_nonopt = optind;
if (first_nonopt > optind)
first_nonopt = optind;
 
if (ordering == PERMUTE)
{
/* If we have just processed some options following some non-options,
exchange them so that the options come first. */
 
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (last_nonopt != optind)
first_nonopt = optind;
 
/* Skip any additional non-options
and extend the range of non-options previously skipped. */
 
while (optind < argc && NONOPTION_P)
optind++;
last_nonopt = optind;
}
 
/* The special ARGV-element `--' means premature end of options.
Skip it like a null option,
then exchange with previous non-options as if it were an option,
then skip everything else like a non-option. */
 
if (optind != argc && !strcmp (argv[optind], "--"))
{
optind++;
 
if (first_nonopt != last_nonopt && last_nonopt != optind)
exchange ((char **) argv);
else if (first_nonopt == last_nonopt)
first_nonopt = optind;
last_nonopt = argc;
 
optind = argc;
}
 
/* If we have done all the ARGV-elements, stop the scan
and back over any non-options that we skipped and permuted. */
 
if (optind == argc)
{
/* Set the next-arg-index to point at the non-options
that we previously skipped, so the caller will digest them. */
if (first_nonopt != last_nonopt)
optind = first_nonopt;
return -1;
}
 
/* If we have come to a non-option and did not permute it,
either stop the scan or describe it to the caller and pass it by. */
 
if (NONOPTION_P)
{
if (ordering == REQUIRE_ORDER)
return -1;
optarg = argv[optind++];
return 1;
}
 
/* We have found another option-ARGV-element.
Skip the initial punctuation. */
 
nextchar = (argv[optind] + 1
+ (longopts != NULL && argv[optind][1] == '-'));
}
 
/* Decode the current option-ARGV-element. */
 
/* Check whether the ARGV-element is a long option.
 
If long_only and the ARGV-element has the form "-f", where f is
a valid short option, don't consider it an abbreviated form of
a long option that starts with f. Otherwise there would be no
way to give the -f short option.
 
On the other hand, if there's a long option "fubar" and
the ARGV-element is "-fu", do consider that an abbreviation of
the long option, just like "--fu", and not "-f" with arg "u".
 
This distinction seems to be the most useful approach. */
 
if (longopts != NULL
&& (argv[optind][1] == '-'
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
{
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = -1;
int option_index;
 
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
 
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((unsigned int) (nameend - nextchar)
== (unsigned int) strlen (p->name))
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
/* Second or later nonexact match found. */
ambig = 1;
}
 
if (ambig && !exact)
{
if (opterr)
fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[optind]);
nextchar += strlen (nextchar);
optind++;
optopt = 0;
return '?';
}
 
if (pfound != NULL)
{
option_index = indfound;
optind++;
if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
if (opterr)
{
if (argv[optind - 1][1] == '-')
/* --option */
fprintf (stderr,
_("%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
else
/* +option or -option */
fprintf (stderr,
_("%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[optind - 1][0], pfound->name);
}
 
nextchar += strlen (nextchar);
 
optopt = pfound->val;
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
optarg = argv[optind++];
else
{
if (opterr)
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
 
/* Can't find it as a long option. If this is not getopt_long_only,
or the option starts with '--' or is not a valid short
option, then it's an error.
Otherwise interpret it as a short option. */
if (!long_only || argv[optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL)
{
if (opterr)
{
if (argv[optind][1] == '-')
/* --option */
fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
else
/* +option or -option */
fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[optind][0], nextchar);
}
nextchar = (char *) "";
optind++;
optopt = 0;
return '?';
}
}
 
/* Look at and handle the next short option-character. */
 
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
 
/* Increment `optind' when we start to process its last character. */
if (*nextchar == '\0')
++optind;
 
if (temp == NULL || c == ':')
{
if (opterr)
{
if (posixly_correct)
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: illegal option -- %c\n"),
argv[0], c);
else
fprintf (stderr, _("%s: invalid option -- %c\n"),
argv[0], c);
}
optopt = c;
return '?';
}
/* Convenience. Treat POSIX -W foo same as long option --foo */
if (temp[0] == 'W' && temp[1] == ';')
{
char *nameend;
const struct option *p;
const struct option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = 0;
int option_index;
 
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr)
{
/* 1003.2 specifies the format of this message. */
fprintf (stderr, _("%s: option requires an argument -- %c\n"),
argv[0], c);
}
optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
return c;
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
 
/* optarg is now the argument, see if it's in the
table of longopts. */
 
for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
/* Do nothing. */ ;
 
/* Test all long options for either exact match
or abbreviated matches. */
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((unsigned int) (nameend - nextchar) == strlen (p->name))
{
/* Exact match found. */
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
/* First nonexact match found. */
pfound = p;
indfound = option_index;
}
else
/* Second or later nonexact match found. */
ambig = 1;
}
if (ambig && !exact)
{
if (opterr)
fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
argv[0], argv[optind]);
nextchar += strlen (nextchar);
optind++;
return '?';
}
if (pfound != NULL)
{
option_index = indfound;
if (*nameend)
{
/* Don't test has_arg with >, because some C compilers don't
allow it to be used on enums. */
if (pfound->has_arg)
optarg = nameend + 1;
else
{
if (opterr)
fprintf (stderr, _("\
%s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name);
 
nextchar += strlen (nextchar);
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (optind < argc)
optarg = argv[optind++];
else
{
if (opterr)
fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[optind - 1]);
nextchar += strlen (nextchar);
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
nextchar = NULL;
return 'W'; /* Let the application handle it. */
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
/* This is an option that accepts an argument optionally. */
if (*nextchar != '\0')
{
optarg = nextchar;
optind++;
}
else
optarg = NULL;
nextchar = NULL;
}
else
{
/* This is an option that requires an argument. */
if (*nextchar != '\0')
{
optarg = nextchar;
/* If we end this ARGV-element by taking the rest as an arg,
we must advance to the next element now. */
optind++;
}
else if (optind == argc)
{
if (opterr)
{
/* 1003.2 specifies the format of this message. */
fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
}
optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
}
else
/* We already incremented `optind' once;
increment it again when taking next ARGV-elt as argument. */
optarg = argv[optind++];
nextchar = NULL;
}
}
return c;
}
}
 
int
getopt (argc, argv, optstring)
int argc;
char *const *argv;
const char *optstring;
{
return _getopt_internal (argc, argv, optstring,
(const struct option *) 0,
(int *) 0,
0);
}
 
#endif /* Not ELIDE_CODE. */
#ifdef TEST
 
/* Compile with -DTEST to make an executable for use in testing
the above definition of `getopt'. */
 
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
 
while (1)
{
int this_option_optind = optind ? optind : 1;
 
c = getopt (argc, argv, "abc:d:0123456789");
if (c == -1)
break;
 
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
 
case 'a':
printf ("option a\n");
break;
 
case 'b':
printf ("option b\n");
break;
 
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
 
case '?':
break;
 
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
 
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
 
exit (0);
}
 
#endif /* TEST */
New file
/httptunnel/port/daemon.c
@@ -0,0 +1,41 @@
/*
port/daemon.c
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#include "config.h"
 
#ifndef HAVE_DAEMON
 
#include <unistd_.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
int
daemon (int nochdir, int noclose)
{
if (fork () != 0)
exit (0);
 
if (!nochdir)
chdir ("/");
 
close (0);
close (1);
close (2);
 
if (noclose == 0)
{
open ("/dev/null", O_RDONLY);
open ("/dev/null", O_WRONLY);
open ("/dev/null", O_WRONLY);
}
 
/* FIXME: disassociate from controlling terminal. */
 
return 0;
}
 
#endif /* HAVE_DAEMON */
New file
/httptunnel/port/getopt1.c
@@ -0,0 +1,191 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97 Free Software Foundation, Inc.
 
the C library, however. The master source lives in /gd/gnu/lib.
 
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
 
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
 
#include "getopt.h"
 
#if !defined (__STDC__) || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
 
#include <stdio_.h>
 
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
 
#define GETOPT_INTERFACE_VERSION 2
#if !defined (_LIBC) && defined (__GLIBC__) && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
 
#ifndef ELIDE_CODE
 
 
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
 
#ifndef NULL
#define NULL 0
#endif
 
int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
 
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
 
int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
 
 
#endif /* Not ELIDE_CODE. */
#ifdef TEST
 
#include <stdio_.h>
 
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
 
while (1)
{
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
 
c = getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
 
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
 
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
 
case 'a':
printf ("option a\n");
break;
 
case 'b':
printf ("option b\n");
break;
 
case 'c':
printf ("option c with value `%s'\n", optarg);
break;
 
case 'd':
printf ("option d with value `%s'\n", optarg);
break;
 
case '?':
break;
 
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
 
if (optind < argc)
{
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
 
exit (0);
}
 
#endif /* TEST */
New file
/httptunnel/port/syslog_.h
@@ -0,0 +1,24 @@
/*
port/syslog_.h
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
#ifndef PORT_SYSLOG_H
#define PORT_SYSLOG_H
 
#include "config.h"
 
#include <stdarg.h>
 
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#else
void syslog (int level, char *fmt0, ...);
#endif
 
#ifndef HAVE_VSYSLOG
void vsyslog (int level, const char *fmt0, va_list ap);
#endif
 
#endif

Property changes:

Name: bugtraq:number
+ true

/httptunnel/port
New file
/httptunnel/AUTHORS
@@ -0,0 +1,27 @@
Programming: Lars Brinkhoff <lars@nocrew.org>
Research: Stefan Berndtsson <stefan@nocrew.org>
Magnus Lundström <logic@nocrew.org>
Disclaimer: Barak Pearlmutter <bap@cs.unm.edu>
Documentation: Teemu Hukkanen <tjhukkan@fishpool.fi>
getopt_long usage: Taken from the manual page.
getopt_long code: Taken from GNU fileutils-4.0.
Patches: Tomas Berndtsson <tomas@nocrew.org> (Solaris)
Andrew Gray <agray@cryogen.com> (Solaris, AIX)
Larry Gensch <larry.gensch@digital.com> (Digital UNIX)
John Bley <jbb6@acpub.duke.edu>
Andrew Mobbs <andrewm@chiark.greenend.org.uk>
Krishna Swaroop <krishna@pnc.cmc.stph.net>
Philip Craig <philip@pobox.com> (Windows)
Jeffrey S Laing <lain@ns.jfl.com>
Ludovic Rousseau <rousseau@wallace.gemplus.fr>
Shimayoshi Takao <simayosi@img.sdl.melco.co.jp>
Chris Lesiak <clesiak@licor.com>
Albert Chin-A-Young <china@thewrittenword.com>
Raphael Manfredi <Raphael.Manfredi@st.com>
Fumitoshi UKAI <ukai@debian.or.jp>
Brian Somers <brian@Awfulhak.org>
Sampo Niskanen <sampo.niskanen@iki.fi>
Testing: Philip Craig <philip@pobox.com>
FAQ: Lars Brinkhoff <lars@nocrew.org>
Christian Brideau <cbrideau@newbridge.com>
... and many novice users.
New file
/httptunnel/tunnel.c
@@ -0,0 +1,1453 @@
/*
tunnel.c
 
Copyright (C) 1999, 2000 Lars Brinkhoff. See COPYING for terms and conditions.
 
See tunnel.h for some documentation about the programming interface.
*/
 
#include <time.h>
#include <stdio.h>
#include <netdb_.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/poll_.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
 
#include "http.h"
#include "tunnel.h"
#include "common.h"
 
/* #define IO_COUNT_HTTP_HEADER */
/* #define USE_SHUTDOWN */
 
#define READ_TRAIL_TIMEOUT (1 * 1000) /* milliseconds */
#define ACCEPT_TIMEOUT 10 /* seconds */
 
#define min(a, b) ((a) < (b) ? (a) : (b))
#define TUNNEL_IN 1
#define TUNNEL_OUT 2
 
#if SIZEOF_CHAR == 1
typedef unsigned char Request;
#else
#error "FIXME: Can't handle SIZEOF_CHAR != 1"
#endif
 
#if SIZEOF_SHORT == 2
typedef unsigned short Length;
#else
#error "FIXME: Can't handle SIZEOF_SHORT != 2"
#endif
 
enum tunnel_request
{
TUNNEL_SIMPLE = 0x40,
TUNNEL_OPEN = 0x01,
TUNNEL_DATA = 0x02,
TUNNEL_PADDING = 0x03,
TUNNEL_ERROR = 0x04,
TUNNEL_PAD1 = TUNNEL_SIMPLE | 0x05,
TUNNEL_CLOSE = TUNNEL_SIMPLE | 0x06,
TUNNEL_DISCONNECT = TUNNEL_SIMPLE | 0x07
};
 
static inline const char *
REQ_TO_STRING (Request request)
{
switch (request)
{
case TUNNEL_OPEN: return "TUNNEL_OPEN";
case TUNNEL_DATA: return "TUNNEL_DATA";
case TUNNEL_PADDING: return "TUNNEL_PADDING";
case TUNNEL_ERROR: return "TUNNEL_ERROR";
case TUNNEL_PAD1: return "TUNNEL_PAD1";
case TUNNEL_CLOSE: return "TUNNEL_CLOSE";
case TUNNEL_DISCONNECT: return "TUNNEL_DISCONNECT";
default: return "(unknown)";
}
}
 
struct tunnel
{
int in_fd, out_fd;
int server_socket;
Http_destination dest;
struct sockaddr_in address;
size_t bytes;
size_t content_length;
char buf[65536];
char *buf_ptr;
size_t buf_len;
int padding_only;
size_t in_total_raw;
size_t in_total_data;
size_t out_total_raw;
size_t out_total_data;
time_t out_connect_time;
int strict_content_length;
int keep_alive;
int max_connection_age;
};
 
static const size_t sizeof_header = sizeof (Request) + sizeof (Length);
 
static inline int
tunnel_is_disconnected (Tunnel *tunnel)
{
return tunnel->out_fd == -1;
}
 
static inline int
tunnel_is_connected (Tunnel *tunnel)
{
return !tunnel_is_disconnected (tunnel);
}
 
static inline int
tunnel_is_server (Tunnel *tunnel)
{
return tunnel->server_socket != -1;
}
 
static inline int
tunnel_is_client (Tunnel *tunnel)
{
return !tunnel_is_server (tunnel);
}
 
#if 1
static int
get_proto_number (const char *name)
{
struct protoent *p;
int number;
 
p = getprotobyname (name);
if (p == NULL)
number = -1;
else
number = p->p_proto;
endprotoent ();
 
return number;
}
#endif
 
static int
tunnel_in_setsockopts (int fd)
{
#ifdef SO_RCVLOWAT
int tcp = get_proto_number ("tcp");
 
if (tcp != -1)
{
int i, n;
 
i = 1;
if (setsockopt (fd,
tcp,
SO_RCVLOWAT,
(void *)&i,
sizeof i) == -1)
{
log_debug ("tunnel_in_setsockopts: non-fatal SO_RCVLOWAT error: %s",
strerror (errno));
}
n = sizeof i;
getsockopt (fd,
tcp,
SO_RCVLOWAT,
(void *)&i,
&n);
log_debug ("tunnel_out_setsockopts: SO_RCVLOWAT: %d", i);
}
#endif /* SO_RCVLOWAT */
 
return 0;
}
 
static int
tunnel_out_setsockopts (int fd)
{
#ifdef SO_SNDLOWAT
{
int tcp = get_proto_number ("tcp");
int i, n;
if (tcp != -1)
{
i = 1;
if (setsockopt (fd,
tcp,
SO_SNDLOWAT,
(void *)&i,
sizeof i) == -1)
{
log_debug ("tunnel_out_setsockopts: "
"non-fatal SO_SNDLOWAT error: %s",
strerror (errno));
}
n = sizeof i;
getsockopt (fd,
tcp,
SO_SNDLOWAT,
(void *)&i,
&n);
log_debug ("tunnel_out_setsockopts: non-fatal SO_SNDLOWAT: %d", i);
}
}
#endif /* SO_SNDLOWAT */
 
#ifdef SO_LINGER
{
struct linger l;
int n;
 
l.l_onoff = 1;
l.l_linger = 20 * 100; /* linger for 20 seconds */
if (setsockopt (fd,
SOL_SOCKET,
SO_LINGER,
(void *)&l,
sizeof l) == -1)
{
log_debug ("tunnel_out_setsockopts: non-fatal SO_LINGER error: %s",
strerror (errno));
}
n = sizeof l;
getsockopt (fd,
SOL_SOCKET,
SO_LINGER,
(void *)&l,
&n);
log_debug ("tunnel_out_setsockopts: SO_LINGER: onoff=%d linger=%d",
l.l_onoff, l.l_linger);
}
#endif /* SO_LINGER */
 
#ifdef TCP_NODELAY
{
int tcp = get_proto_number ("tcp");
int i, n;
if (tcp != -1)
{
i = 1;
if (setsockopt (fd,
tcp,
TCP_NODELAY,
(void *)&i,
sizeof i) == -1)
{
log_debug ("tunnel_out_setsockopts: "
"non-fatal TCP_NODELAY error: %s",
strerror (errno));
}
n = sizeof i;
getsockopt (fd,
tcp,
TCP_NODELAY,
(void *)&i,
&n);
log_debug ("tunnel_out_setsockopts: non-fatal TCP_NODELAY: %d", i);
}
}
#else
#ifdef SO_SNDBUF
{
int i, n;
 
i = 0;
if (setsockopt (fd,
SOL_SOCKET,
SO_SNDBUF,
(void *)&i,
sizeof i) == -1)
{
log_debug ("tunnel_out_setsockopts: non-fatal SO_SNDBUF error: %s",
strerror (errno));
}
n = sizeof i;
getsockopt (fd,
SOL_SOCKET,
SO_SNDBUF,
(void *)&i,
&n);
log_debug ("tunnel_out_setsockopts: SO_SNDBUF: %d", i);
}
#endif /* SO_SNDBUF */
#endif /* TCP_NODELAY */
 
#ifdef SO_KEEPALIVE
{
int i, n;
 
i = 1;
if (setsockopt (fd,
SOL_SOCKET,
SO_KEEPALIVE,
(void *)&i,
sizeof i) == -1)
{
log_debug ("tunnel_out_setsockopts: non-fatal SO_KEEPALIVE error: %s",
strerror (errno));
}
n = sizeof i;
getsockopt (fd,
SOL_SOCKET,
SO_KEEPALIVE,
(void *)&i,
&n);
log_debug ("tunnel_out_setsockopts: SO_KEEPALIVE: %d", i);
}
#endif /* SO_KEEPALIVE */
 
return 0;
}
 
static void
tunnel_out_disconnect (Tunnel *tunnel)
{
if (tunnel_is_disconnected (tunnel))
return;
 
#ifdef DEBUG_MODE
if (tunnel_is_client (tunnel) &&
tunnel->bytes != tunnel->content_length + 1)
log_error ("tunnel_out_disconnect: warning: "
"bytes=%d != content_length=%d",
tunnel->bytes, tunnel->content_length + 1);
#endif
 
close (tunnel->out_fd);
tunnel->out_fd = -1;
tunnel->bytes = 0;
tunnel->buf_ptr = tunnel->buf;
tunnel->buf_len = 0;
 
log_debug ("tunnel_out_disconnect: output disconnected");
}
 
static void
tunnel_in_disconnect (Tunnel *tunnel)
{
if (tunnel->in_fd == -1)
return;
 
close (tunnel->in_fd);
tunnel->in_fd = -1;
 
log_debug ("tunnel_in_disconnect: input disconnected");
}
 
static int
tunnel_out_connect (Tunnel *tunnel)
{
ssize_t n;
 
if (tunnel_is_connected (tunnel))
{
log_debug ("tunnel_out_connect: already connected");
tunnel_out_disconnect (tunnel);
}
 
tunnel->out_fd = do_connect (&tunnel->address);
if (tunnel->out_fd == -1)
{
log_error ("tunnel_out_connect: do_connect (%d.%d.%d.%d:%u) error: %s",
ntohl (tunnel->address.sin_addr.s_addr) >> 24,
(ntohl (tunnel->address.sin_addr.s_addr) >> 16) & 0xff,
(ntohl (tunnel->address.sin_addr.s_addr) >> 8) & 0xff,
ntohl (tunnel->address.sin_addr.s_addr) & 0xff,
ntohs (tunnel->address.sin_port),
strerror (errno));
return -1;
}
 
tunnel_out_setsockopts (tunnel->out_fd);
 
#ifdef USE_SHUTDOWN
shutdown (tunnel->out_fd, 0);
#endif
 
/* + 1 to allow for TUNNEL_DISCONNECT */
n = http_post (tunnel->out_fd,
&tunnel->dest,
tunnel->content_length + 1);
if (n == -1)
return -1;
#ifdef IO_COUNT_HTTP_HEADER
tunnel->out_total_raw += n;
log_annoying ("tunnel_out_connect: out_total_raw = %u",
tunnel->out_total_raw);
#endif
 
tunnel->bytes = 0;
tunnel->buf_ptr = tunnel->buf;
tunnel->buf_len = 0;
tunnel->padding_only = TRUE;
time (&tunnel->out_connect_time);
 
log_debug ("tunnel_out_connect: output connected");
 
return 0;
}
 
static int
tunnel_in_connect (Tunnel *tunnel)
{
Http_response *response;
ssize_t n;
 
log_verbose ("tunnel_in_connect()");
 
if (tunnel->in_fd != -1)
{
log_error ("tunnel_in_connect: already connected");
return -1;
}
 
tunnel->in_fd = do_connect (&tunnel->address);
if (tunnel->in_fd == -1)
{
log_error ("tunnel_in_connect: do_connect() error: %s",
strerror (errno));
return -1;
}
 
tunnel_in_setsockopts (tunnel->in_fd);
 
if (http_get (tunnel->in_fd, &tunnel->dest) == -1)
return -1;
 
#ifdef USE_SHUTDOWN
if (shutdown (tunnel->in_fd, 1) == -1)
{
log_error ("tunnel_in_connect: shutdown() error: %s",
strerror (errno));
return -1;
}
#endif
 
n = http_parse_response (tunnel->in_fd, &response);
if (n <= 0)
{
if (n == 0)
log_error ("tunnel_in_connect: no response; peer "
"closed connection");
else
log_error ("tunnel_in_connect: no response; error: %s",
strerror (errno));
}
else if (response->major_version != 1 ||
(response->minor_version != 1 &&
response->minor_version != 0))
{
log_error ("tunnel_in_connect: unknown HTTP version: %d.%d",
response->major_version, response->minor_version);
n = -1;
}
else if (response->status_code != 200)
{
log_error ("tunnel_in_connect: HTTP error %d", response->status_code);
errno = http_error_to_errno (-response->status_code);
n = -1;
}
 
if (response)
http_destroy_response (response);
 
if (n > 0)
{
#ifdef IO_COUNT_HTTP_HEADER
tunnel->in_total_raw += n;
log_annoying ("tunnel_in_connect: in_total_raw = %u",
tunnel->in_total_raw);
#endif
}
else
{
return n;
}
 
log_debug ("tunnel_in_connect: input connected");
return 1;
}
 
static inline ssize_t
tunnel_write_data (Tunnel *tunnel, void *data, size_t length)
{
if (write_all (tunnel->out_fd, data, length) == -1)
{
log_error ("tunnel_write_data: write error: %s", strerror (errno));
return -1;
}
tunnel->bytes += length;
return length;
}
 
static int
tunnel_write_request (Tunnel *tunnel, Request request,
void *data, Length length)
{
if (tunnel->bytes + sizeof request +
(data ? sizeof length + length : 0) > tunnel->content_length)
tunnel_padding (tunnel, tunnel->content_length - tunnel->bytes);
 
#if 1 /* FIXME: this is a kludge */
{
time_t t;
 
time (&t);
if (tunnel_is_client (tunnel) &&
tunnel_is_connected (tunnel) &&
t - tunnel->out_connect_time > tunnel->max_connection_age)
{
char c = TUNNEL_DISCONNECT;
 
log_debug ("tunnel_write_request: connection > %d seconds old",
tunnel->max_connection_age);
 
if (tunnel->strict_content_length)
{
int l = tunnel->content_length - tunnel->bytes - 1;
 
log_debug ("tunnel_write_request: write padding (%d bytes)",
tunnel->content_length - tunnel->bytes - 1);
if (l > 3)
{
char c;
short s;
int i;
 
c = TUNNEL_PADDING;
tunnel_write_data (tunnel, &c, sizeof c);
 
s = htons(l-2);
tunnel_write_data (tunnel, &s, sizeof s);
 
l -= 2;
c = 0;
for (i=0; i<l; i++)
tunnel_write_data (tunnel, &c, sizeof c);
}
else
{
char c = TUNNEL_PAD1;
int i;
for (i=0; i<l; i++)
tunnel_write_data (tunnel, &c, sizeof c);
}
}
 
log_debug ("tunnel_write_request: closing old connection");
if (tunnel_write_data (tunnel, &c, sizeof c) <= 0)
return -1;
tunnel_out_disconnect (tunnel);
}
}
#endif
 
if (tunnel_is_disconnected (tunnel))
{
if (tunnel_is_client (tunnel))
{
if (tunnel_out_connect (tunnel) == -1)
return -1;
}
else
{
#if 0
log_error ("tunnel_write_request: output is disconnected");
errno = EIO;
return -1;
#else
if (tunnel_accept (tunnel) == -1)
return -1;
#endif
}
}
 
if (request != TUNNEL_PADDING && request != TUNNEL_PAD1)
tunnel->padding_only = FALSE;
 
if (tunnel_write_data (tunnel, &request, sizeof request) == -1)
{
if (errno != EPIPE)
return -1;
 
tunnel_out_disconnect (tunnel);
if (tunnel_is_client (tunnel))
tunnel_out_connect (tunnel);
else
{
log_error ("tunnel_write_request: couldn't write request: "
"output is disconnected");
errno = EIO;
return -1;
}
/* return tunnel_write_request (tunnel, request, data, length); */
if (tunnel_write_data (tunnel, &request, sizeof request) == -1)
return -1;
}
 
if (data)
{
Length network_length = htons ((short)length);
if (tunnel_write_data (tunnel,
&network_length,
sizeof network_length) == -1)
return -1;
 
#ifdef DEBUG_MODE
if (request == TUNNEL_DATA && debug_level >= 5)
{
log_annoying ("tunnel_write_request: TUNNEL_DATA:");
dump_buf (debug_file, data, (size_t)length);
}
#endif
 
if (tunnel_write_data (tunnel, data, (size_t)length) == -1)
return -1;
}
 
if (data)
{
tunnel->out_total_raw += 3 + length;
 
if (request == TUNNEL_DATA)
log_verbose ("tunnel_write_request: %s (%d)",
REQ_TO_STRING (request), length);
else
log_debug ("tunnel_write_request: %s (%d)",
REQ_TO_STRING (request), length);
}
else
{
tunnel->out_total_raw += 1;
log_debug ("tunnel_write_request: %s", REQ_TO_STRING (request));
}
 
log_annoying ("tunnel_write_data: out_total_raw = %u",
tunnel->out_total_raw);
 
#ifdef DEBUG_MODE
if (tunnel->bytes > tunnel->content_length)
log_debug ("tunnel_write_request: tunnel->bytes > tunnel->content_length");
#endif
if (tunnel->bytes >= tunnel->content_length)
{
char c = TUNNEL_DISCONNECT;
tunnel_write_data (tunnel, &c, sizeof c);
tunnel_out_disconnect (tunnel);
#if 0
if (tunnel_is_server (tunnel))
tunnel_accept (tunnel);
#endif
}
 
return 0;
}
 
int
tunnel_connect (Tunnel *tunnel)
{
char auth_data[1] = { 42 }; /* dummy data, not used by server */
 
log_verbose ("tunnel_connect()");
 
if (tunnel_is_connected (tunnel))
{
log_error ("tunnel_connect: already connected");
errno = EINVAL;
return -1;
}
 
if (tunnel_write_request (tunnel, TUNNEL_OPEN,
auth_data, sizeof auth_data) == -1)
return -1;
 
if (tunnel_in_connect (tunnel) <= 0)
return -1;
 
return 0;
}
 
static inline int
tunnel_write_or_padding (Tunnel *tunnel, Request request, void *data,
size_t length)
{
static char padding[65536];
size_t n, remaining;
char *wdata = data;
 
for (remaining = length; remaining > 0; remaining -= n, wdata += n)
{
if (tunnel->bytes + remaining > tunnel->content_length - sizeof_header &&
tunnel->content_length - tunnel->bytes > sizeof_header)
n = tunnel->content_length - sizeof_header - tunnel->bytes;
else if (remaining > tunnel->content_length - sizeof_header)
n = tunnel->content_length - sizeof_header;
else
n = remaining;
 
if (n > 65535)
n = 65535;
 
if (request == TUNNEL_PADDING)
{
if (n + sizeof_header > remaining)
n = remaining - sizeof_header;
if (tunnel_write_request (tunnel, request, padding, n) == -1)
break;
n += sizeof_header;
}
else
{
if (tunnel_write_request (tunnel, request, wdata, n) == -1)
break;
}
}
 
return length - remaining;
}
 
ssize_t
tunnel_write (Tunnel *tunnel, void *data, size_t length)
{
ssize_t n;
 
n = tunnel_write_or_padding (tunnel, TUNNEL_DATA, data, length);
tunnel->out_total_data += length;
log_verbose ("tunnel_write: out_total_data = %u", tunnel->out_total_data);
return n;
}
 
ssize_t
tunnel_padding (Tunnel *tunnel, size_t length)
{
if (length < sizeof_header + 1)
{
int i;
 
for (i = 0; i < length; i++)
tunnel_write_request (tunnel, TUNNEL_PAD1, NULL, 0);
return length;
}
 
return tunnel_write_or_padding (tunnel, TUNNEL_PADDING, NULL, length);
}
 
int
tunnel_close (Tunnel *tunnel)
{
struct pollfd p;
char buf[10240];
ssize_t n;
 
if (tunnel->strict_content_length)
{
log_debug ("tunnel_close: write padding (%d bytes)",
tunnel->content_length - tunnel->bytes - 1);
tunnel_padding (tunnel, tunnel->content_length - tunnel->bytes - 1);
}
 
log_debug ("tunnel_close: write TUNNEL_CLOSE request");
tunnel_write_request (tunnel, TUNNEL_CLOSE, NULL, 0);
 
tunnel_out_disconnect (tunnel);
 
log_debug ("tunnel_close: reading trailing data from input ...");
p.fd = tunnel->in_fd;
p.events = POLLIN;
while (poll (&p, 1, READ_TRAIL_TIMEOUT) > 0)
{
if (p.revents & POLLIN)
{
n = read (tunnel->in_fd, buf, sizeof buf);
if (n > 0)
{
log_annoying ("read (%d, %p, %d) = %d",
tunnel->in_fd, buf, sizeof buf, n);
continue;
}
else if (n == -1 && errno == EAGAIN)
continue;
else if (n == -1)
log_debug ("tunnel_close: ... error: %s", strerror (errno));
else
log_debug ("tunnel_close: ... done (tunnel closed)");
}
if (p.revents & POLLHUP)
log_debug ("POLLHUP");
if (p.revents & POLLERR)
log_debug ("POLLERR");
if (p.revents & POLLNVAL)
log_debug ("POLLNVAL");
break;
}
 
tunnel_in_disconnect (tunnel);
 
tunnel->buf_len = 0;
tunnel->in_total_raw = 0;
tunnel->in_total_data = 0;
tunnel->out_total_raw = 0;
tunnel->out_total_data = 0;
 
return 0;
}
 
static int
tunnel_read_request (Tunnel *tunnel, enum tunnel_request *request,
unsigned char *buf, size_t *length)
{
Request req;
Length len;
ssize_t n;
 
log_annoying ("read (%d, %p, %d) ...", tunnel->in_fd, &req, 1);
n = read (tunnel->in_fd, &req, 1);
log_annoying ("... = %d", n);
if (n == -1)
{
if (errno != EAGAIN)
log_error ("tunnel_read_request: error reading request: %s",
strerror (errno));
return n;
}
else if (n == 0)
{
log_debug ("tunnel_read_request: connection closed by peer");
tunnel_in_disconnect (tunnel);
 
if (tunnel_is_client (tunnel)
&& tunnel_in_connect (tunnel) == -1)
return -1;
 
errno = EAGAIN;
return -1;
}
*request = req;
tunnel->in_total_raw += n;
log_annoying ("request = 0x%x (%s)", req, REQ_TO_STRING (req));
 
if (req & TUNNEL_SIMPLE)
{
log_annoying ("tunnel_read_request: in_total_raw = %u",
tunnel->in_total_raw);
log_debug ("tunnel_read_request: %s", REQ_TO_STRING (req));
*length = 0;
return 1;
}
 
n = read_all (tunnel->in_fd, &len, 2);
if (n <= 0)
{
log_error ("tunnel_read_request: error reading request length: %s",
strerror (errno));
if (n == 0)
errno = EIO;
return -1;
}
len = ntohs (len);
*length = len;
tunnel->in_total_raw += n;
log_annoying ("length = %d", len);
 
if (len > 0)
{
n = read_all (tunnel->in_fd, buf, (size_t)len);
if (n <= 0)
{
log_error ("tunnel_read_request: error reading request data: %s",
strerror (errno));
if (n == 0)
errno = EIO;
return -1;
}
tunnel->in_total_raw += n;
log_annoying ("tunnel_read_request: in_total_raw = %u",
tunnel->in_total_raw);
}
 
if (req == TUNNEL_DATA)
log_verbose ("tunnel_read_request: %s (%d)",
REQ_TO_STRING (req), len);
else
log_debug ("tunnel_read_request: %s (%d)",
REQ_TO_STRING (req), len);
 
return 1;
}
 
ssize_t
tunnel_read (Tunnel *tunnel, void *data, size_t length)
{
enum tunnel_request req;
size_t len;
ssize_t n;
 
if (tunnel->buf_len > 0)
{
n = min (tunnel->buf_len, length);
memcpy (data, tunnel->buf_ptr, n);
tunnel->buf_ptr += n;
tunnel->buf_len -= n;
return n;
}
 
if (tunnel->in_fd == -1)
{
if (tunnel_is_client (tunnel))
{
if (tunnel_in_connect (tunnel) == -1)
return -1;
}
else
{
#if 1
if (tunnel_accept (tunnel) == -1)
return -1;
#else
errno = EAGAIN;
return -1;
#endif
}
 
errno = EAGAIN;
return -1;
}
 
if (tunnel->out_fd == -1 && tunnel_is_server (tunnel))
{
tunnel_accept (tunnel);
errno = EAGAIN;
return -1;
}
 
if (tunnel_read_request (tunnel, &req, tunnel->buf, &len) <= 0)
{
log_annoying ("tunnel_read_request returned <= 0, returning -1");
return -1;
}
 
switch (req)
{
case TUNNEL_OPEN:
/* do something with tunnel->buf */
break;
 
case TUNNEL_DATA:
tunnel->buf_ptr = tunnel->buf;
tunnel->buf_len = len;
tunnel->in_total_data += len;
log_verbose ("tunnel_read: in_total_data = %u", tunnel->in_total_data);
return tunnel_read (tunnel, data, length);
 
case TUNNEL_PADDING:
/* discard data */
break;
 
case TUNNEL_PAD1:
/* do nothing */
break;
 
case TUNNEL_ERROR:
tunnel->buf[len] = 0;
log_error ("tunnel_read: received error: %s", tunnel->buf);
errno = EIO;
return -1;
 
case TUNNEL_CLOSE:
return 0;
 
case TUNNEL_DISCONNECT:
tunnel_in_disconnect (tunnel);
 
if (tunnel_is_client (tunnel)
&& tunnel_in_connect (tunnel) == -1)
return -1;
 
errno = EAGAIN;
return -1;
 
default:
log_error ("tunnel_read: protocol error: unknown request 0x%02x", req);
errno = EINVAL;
return -1;
}
 
errno = EAGAIN;
return -1;
}
 
int
tunnel_pollin_fd (Tunnel *tunnel)
{
if (tunnel_is_server (tunnel) &&
(tunnel->in_fd == -1 || tunnel->out_fd == -1))
{
if (tunnel->in_fd == -1)
log_verbose ("tunnel_pollin_fd: in_fd = -1; returning server_socket = %d",
tunnel->server_socket);
else
log_verbose ("tunnel_pollin_fd: out_fd = -1; returning server_socket = %d",
tunnel->server_socket);
return tunnel->server_socket;
}
else if (tunnel->in_fd != -1)
return tunnel->in_fd;
else
{
log_error ("tunnel_pollin_fd: returning -1");
return -1;
}
}
 
/*
If the write connection is up and needs padding to the block length
specified in the second argument, send some padding.
*/
 
int
tunnel_maybe_pad (Tunnel *tunnel, size_t length)
{
size_t padding;
 
if (tunnel_is_disconnected (tunnel) ||
tunnel->bytes % length == 0 ||
tunnel->padding_only)
return 0;
 
padding = length - tunnel->bytes % length;
if (padding > tunnel->content_length - tunnel->bytes)
padding = tunnel->content_length - tunnel->bytes;
 
return tunnel_padding (tunnel, padding);
}
 
#if 0
ssize_t
old_parse_header (int s, int *type)
{
static const char *end_of_header = "\r\n\r\n";
ssize_t n, len = 0;
char c;
int i;
 
*type = -1;
 
n = read_all (s, &c, 1);
if (n != 1)
return -1;
len += n;
 
if (c == 'P')
*type = TUNNEL_IN;
else if (c == 'G')
*type = TUNNEL_OUT;
else
{
log_error ("parse_header: unknown HTTP request starting with '%c'", c);
errno = EINVAL;
return -1;
}
 
i = 0;
while (i < 4)
{
n = read_all (s, &c, 1);
if (n != 1 && errno != EAGAIN)
return n;
len += n;
 
if (c == end_of_header[i])
i++;
else
i = 0;
}
 
return len;
}
#endif
 
int
tunnel_accept (Tunnel *tunnel)
{
if (tunnel->in_fd != -1 && tunnel->out_fd != -1)
{
log_debug ("tunnel_accept: tunnel already established");
return 0;
}
 
while (tunnel->in_fd == -1 || tunnel->out_fd == -1)
{
struct sockaddr_in addr;
Http_request *request;
struct pollfd p;
ssize_t m;
int len;
int n;
int s;
 
p.fd = tunnel->server_socket;
p.events = POLLIN;
n = poll (&p, 1, (tunnel->in_fd != -1 || tunnel->out_fd != -1 ?
ACCEPT_TIMEOUT * 1000 : -1));
if (n == -1)
{
log_error ("tunnel_accept: poll error: %s", strerror (errno));
return -1;
}
else if (n == 0)
{
log_error ("tunnel_accept: poll timed out");
break;
}
 
len = sizeof addr;
s = accept (tunnel->server_socket, (struct sockaddr *)&addr, &len);
if (s == -1)
{
log_error ("tunnel_accept: accept error: %s", strerror (errno));
return -1;
}
 
log_notice ("connection from %d.%d.%d.%d:%u",
ntohl (addr.sin_addr.s_addr) >> 24,
(ntohl (addr.sin_addr.s_addr) >> 16) & 0xff,
(ntohl (addr.sin_addr.s_addr) >> 8) & 0xff,
ntohl (addr.sin_addr.s_addr) & 0xff,
ntohs (addr.sin_port));
 
m = http_parse_request (s, &request);
if (m <= 0)
return m;
 
if (request->method == -1)
{
log_error ("tunnel_accept: error parsing header: %s",
strerror (errno));
close (s);
}
else if (request->method == HTTP_POST ||
request->method == HTTP_PUT)
{
if (tunnel->in_fd == -1)
{
tunnel->in_fd = s;
 
#ifdef IO_COUNT_HTTP_HEADER
tunnel->in_total_raw += m; /* from parse_header() */
log_annoying ("tunnel_accept: in_total_raw = %u",
tunnel->in_total_raw);
#endif
 
fcntl (tunnel->in_fd,
F_SETFL,
fcntl (tunnel->in_fd, F_GETFL) | O_NONBLOCK);
 
tunnel_in_setsockopts (tunnel->in_fd);
 
log_debug ("tunnel_accept: input connected");
}
else
{
log_error ("rejected tunnel_in: already got a connection");
close (s);
}
}
else if (request->method == HTTP_GET)
{
if (tunnel->out_fd == -1)
{
char str[1024];
 
tunnel->out_fd = s;
 
tunnel_out_setsockopts (tunnel->out_fd);
 
sprintf (str,
"HTTP/1.1 200 OK\r\n"
/* "Date: %s\r\n" */
/* "Server: %s\r\n" */
/* "Last-Modified: %s\r\n" */
/* "ETag: %s\r\n" */
/* "Accept-Ranges: %s\r\n" */
"Content-Length: %d\r\n"
"Connection: close\r\n"
"Pragma: no-cache\r\n"
"Cache-Control: no-cache, no-store, must-revalidate\r\n"
"Expires: 0\r\n" /* FIXME: "0" is not a legitimate HTTP date. */
"Content-Type: text/html\r\n"
"\r\n",
/* +1 to allow for TUNNEL_DISCONNECT */
tunnel->content_length + 1);
if (write_all (tunnel->out_fd, str, strlen (str)) <= 0)
{
log_error ("tunnel_accept: couldn't write GET header: %s",
strerror (errno));
close (tunnel->out_fd);
tunnel->out_fd = -1;
}
else
{
tunnel->bytes = 0;
tunnel->buf_len = 0;
tunnel->buf_ptr = tunnel->buf;
#ifdef IO_COUNT_HTTP_HEADER
tunnel->out_total_raw += strlen (str);
log_annoying ("tunnel_accept: out_total_raw = %u",
tunnel->out_total_raw);
#endif
log_debug ("tunnel_accept: output connected");
}
}
else
{
log_error ("tunnel_accept: rejected tunnel_out: "
"already got a connection");
close (s);
}
}
else
{
log_error ("tunnel_accept: unknown header type");
log_debug ("tunnel_accept: closing connection");
close (s);
}
 
http_destroy_request (request);
}
 
if (tunnel->in_fd == -1 || tunnel->out_fd == -1)
{
log_error ("tunnel_accept: in_fd = %d, out_fd = %d",
tunnel->in_fd, tunnel->out_fd);
 
if (tunnel->in_fd != -1)
close (tunnel->in_fd);
tunnel->in_fd = -1;
log_debug ("tunnel_accept: input disconnected");
 
tunnel_out_disconnect (tunnel);
 
return -1;
}
 
return 0;
}
 
Tunnel *
tunnel_new_server (const char *host, int port, size_t content_length)
{
Tunnel *tunnel;
struct in_addr addr;
struct hostent *hp;
 
if (host == NULL)
addr.s_addr = INADDR_ANY;
else if ((addr.s_addr = inet_addr (host)) == INADDR_NONE)
{
hp = gethostbyname (host);
if (hp == NULL || hp->h_addrtype != AF_INET)
return NULL;
memcpy (&addr, hp->h_addr, hp->h_length);
}
 
tunnel = malloc (sizeof (Tunnel));
if (tunnel == NULL)
return NULL;
 
/* If content_length is 0, a value must be determined automatically. */
/* For now, a default value will do. */
if (content_length == 0)
content_length = DEFAULT_CONTENT_LENGTH;
 
tunnel->in_fd = -1;
tunnel->out_fd = -1;
tunnel->server_socket = -1;
tunnel->dest.host_name = host;
tunnel->dest.host_port = port;
tunnel->buf_ptr = tunnel->buf;
tunnel->buf_len = 0;
/* -1 to allow for TUNNEL_DISCONNECT */
tunnel->content_length = content_length - 1;
tunnel->in_total_raw = 0;
tunnel->in_total_data = 0;
tunnel->out_total_raw = 0;
tunnel->out_total_data = 0;
tunnel->strict_content_length = FALSE;
tunnel->bytes = 0;
 
tunnel->server_socket = server_socket (addr, tunnel->dest.host_port, 1);
if (tunnel->server_socket == -1)
{
log_error ("tunnel_new_server: server_socket (%d) = -1",
tunnel->dest.host_port);
tunnel_destroy (tunnel);
return NULL;
}
 
return tunnel;
}
 
Tunnel *
tunnel_new_client (const char *host, int host_port,
const char *proxy, int proxy_port,
size_t content_length)
{
const char *remote;
int remote_port;
Tunnel *tunnel;
 
log_verbose ("tunnel_new_client (\"%s\", %d, \"%s\", %d, %d)",
host, host_port, proxy ? proxy : "(null)", proxy_port,
content_length);
 
tunnel = malloc (sizeof (Tunnel));
if (tunnel == NULL)
{
log_error ("tunnel_new_client: out of memory");
return NULL;
}
 
tunnel->in_fd = -1;
tunnel->out_fd = -1;
tunnel->server_socket = -1;
tunnel->dest.host_name = host;
tunnel->dest.host_port = host_port;
tunnel->dest.proxy_name = proxy;
tunnel->dest.proxy_port = proxy_port;
tunnel->dest.proxy_authorization = NULL;
tunnel->dest.user_agent = NULL;
/* -1 to allow for TUNNEL_DISCONNECT */
tunnel->content_length = content_length - 1;
tunnel->buf_ptr = tunnel->buf;
tunnel->buf_len = 0;
tunnel->in_total_raw = 0;
tunnel->in_total_data = 0;
tunnel->out_total_raw = 0;
tunnel->out_total_data = 0;
tunnel->strict_content_length = FALSE;
tunnel->bytes = 0;
 
if (tunnel->dest.proxy_name == NULL)
{
remote = tunnel->dest.host_name;
remote_port = tunnel->dest.host_port;
}
else
{
remote = tunnel->dest.proxy_name;
remote_port = tunnel->dest.proxy_port;
}
 
if (set_address (&tunnel->address, remote, remote_port) == -1)
{
log_error ("tunnel_new_client: set_address: %s", strerror (errno));
free (tunnel);
return NULL;
}
 
return tunnel;
}
 
void
tunnel_destroy (Tunnel *tunnel)
{
if (tunnel_is_connected (tunnel) || tunnel->in_fd != -1)
tunnel_close (tunnel);
 
if (tunnel->server_socket != -1)
close (tunnel->server_socket);
 
free (tunnel);
}
 
static int
tunnel_opt (Tunnel *tunnel, const char *opt, void *data, int get_flag)
{
if (strcmp (opt, "strict_content_length") == 0)
{
if (get_flag)
*(int *)data = tunnel->strict_content_length;
else
tunnel->strict_content_length = *(int *)data;
}
else if (strcmp (opt, "keep_alive") == 0)
{
if (get_flag)
*(int *)data = tunnel->keep_alive;
else
tunnel->keep_alive = *(int *)data;
}
else if (strcmp (opt, "max_connection_age") == 0)
{
if (get_flag)
*(int *)data = tunnel->max_connection_age;
else
tunnel->max_connection_age = *(int *)data;
}
else if (strcmp (opt, "proxy_authorization") == 0)
{
if (get_flag)
{
if (tunnel->dest.proxy_authorization == NULL)
*(char **)data = NULL;
else
*(char **)data = strdup (tunnel->dest.proxy_authorization);
}
else
{
if (tunnel->dest.proxy_authorization != NULL)
free ((char *)tunnel->dest.proxy_authorization);
tunnel->dest.proxy_authorization = strdup ((char *)data);
if (tunnel->dest.proxy_authorization == NULL)
return -1;
}
}
else if (strcmp (opt, "user_agent") == 0)
{
if (get_flag)
{
if (tunnel->dest.user_agent == NULL)
*(char **)data = NULL;
else
*(char **)data = strdup (tunnel->dest.user_agent);
}
else
{
if (tunnel->dest.user_agent != NULL)
free ((char *)tunnel->dest.user_agent);
tunnel->dest.user_agent = strdup ((char *)data);
if (tunnel->dest.user_agent == NULL)
return -1;
}
}
else
{
errno = EINVAL;
return -1;
}
 
return 0;
}
 
int
tunnel_setopt (Tunnel *tunnel, const char *opt, void *data)
{
return tunnel_opt (tunnel, opt, data, FALSE);
}
 
int
tunnel_getopt (Tunnel *tunnel, const char *opt, void *data)
{
return tunnel_opt (tunnel, opt, data, TRUE);
}
New file
/httptunnel/tunnel.h
@@ -0,0 +1,87 @@
/*
tunnel.h
 
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
*/
 
/*
This is the programming interface to the HTTP tunnel. It consists
of the following functions:
 
Tunnel *tunnel_new_client (const char *host, int host_port,
const char *proxy, int proxy_port,
size_t content_length);
 
Create a new HTTP tunnel client.
 
Tunnel *tunnel_new_server (const char *host,
int port,
size_t content_length);
 
Create a new HTTP tunnel server. If LENGTH is 0, the Content-Length
of the HTTP GET response will be determined automatically in some way.
If HOST is not NULL, use it to bind the server socket to a specific
network interface.
 
int tunnel_connect (Tunnel *tunnel);
 
Open the tunnel. (Client only.)
 
int tunnel_accept (Tunnel *tunnel);
 
Accept a tunnel connection. (Server only.)
 
int tunnel_pollin_fd (Tunnel *tunnel);
 
Return a file descriptor that can be used to poll for input from
the tunnel.
 
ssize_t tunnel_read (Tunnel *tunnel, void *data, size_t length);
ssize_t tunnel_write (Tunnel *tunnel, void *data, size_t length);
 
Read or write to the tunnel. Same semantics as with read() and
write(). Watch out for return values less than LENGTH.
 
int tunnel_padding (Tunnel *tunnel, size_t length);
 
Send LENGTH pad bytes.
 
int tunnel_maybe_pad (Tunnel *tunnel, size_t length);
 
Pad to nearest even multiple of LENGTH.
 
int tunnel_close (Tunnel *tunnel);
 
Close the tunnel.
 
void tunnel_destroy (Tunnel *tunnel);
*/
 
#ifndef TUNNEL_H
#define TUNNEL_H
 
#include "config.h"
#include <sys/types.h>
 
#define DEFAULT_CONNECTION_MAX_TIME 300
 
typedef struct tunnel Tunnel;
 
extern Tunnel *tunnel_new_client (const char *host, int host_port,
const char *proxy, int proxy_port,
size_t content_length);
extern Tunnel *tunnel_new_server (const char *host, int port,
size_t content_length);
extern int tunnel_connect (Tunnel *tunnel);
extern int tunnel_accept (Tunnel *tunnel);
extern int tunnel_pollin_fd (Tunnel *tunnel);
extern ssize_t tunnel_read (Tunnel *tunnel, void *data, size_t length);
extern ssize_t tunnel_write (Tunnel *tunnel, void *data, size_t length);
extern ssize_t tunnel_padding (Tunnel *tunnel, size_t length);
extern int tunnel_maybe_pad (Tunnel *tunnel, size_t length);
extern int tunnel_setopt (Tunnel *tunnel, const char *opt, void *data);
extern int tunnel_getopt (Tunnel *tunnel, const char *opt, void *data);
extern int tunnel_close (Tunnel *tunnel);
extern void tunnel_destroy (Tunnel *tunnel);
 
#endif /* TUNNEL_H */
New file
/httptunnel/htc.c
@@ -0,0 +1,674 @@
/*
htc.c
 
Copyright (C) 1999, 2000 Lars Brinkhoff. See COPYING for terms and conditions.
 
htc is the client half of httptunnel. httptunnel creates a virtual
two-way data path tunneled in HTTP requests.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd_.h>
#include <signal.h>
#include <sys/poll_.h>
#include <sys/time.h>
#include <sys/stat.h>
 
#include "common.h"
#include "base64.h"
 
#define DEFAULT_PROXY_PORT 8080
#define DEFAULT_PROXY_BUFFER_TIMEOUT 500 /* milliseconds */
 
typedef struct
{
char *me;
char *device;
char *host_name;
int host_port;
char *proxy_name;
int proxy_port;
size_t proxy_buffer_size;
int proxy_buffer_timeout;
size_t content_length;
int forward_port;
int use_std;
int use_daemon;
int strict_content_length;
int keep_alive;
int max_connection_age;
char *proxy_authorization;
char *user_agent;
} Arguments;
 
#define NO_PROXY_BUFFER 0
#define NO_PROXY (NULL)
 
int debug_level = 0;
FILE *debug_file = NULL;
 
static void
usage (FILE *f, const char *me)
{
fprintf (f,
"Usage: %s [OPTION]... HOST[:PORT]\n"
"Set up a httptunnel connection to PORT at HOST (default port is %d).\n"
"When a connection is made, I/O is redirected from the source specified\n"
"by the --device, --forward-port or --stdin-stdout switch to the tunnel.\n"
"\n"
" -A, --proxy-authorization USER:PASSWORD proxy authorization\n"
" -z, --proxy-authorization-file FILE proxy authorization file\n"
" -B, --proxy-buffer-size BYTES assume a proxy buffer size of BYTES bytes\n"
" (k, M, and G postfixes recognized)\n"
" -c, --content-length BYTES use HTTP PUT requests of BYTES size\n"
" (k, M, and G postfixes recognized)\n"
" -d, --device DEVICE use DEVICE for input and output\n"
#ifdef DEBUG_MODE
" -D, --debug [LEVEL] enable debugging mode\n"
#endif
" -F, --forward-port PORT use TCP port PORT for input and output\n"
" -h, --help display this help and exit\n"
" -k, --keep-alive SECONDS send keepalive bytes every SECONDS seconds\n"
" (default is %d)\n"
#ifdef DEBUG_MODE
" -l, --logfile FILE specify file for debugging output\n"
#endif
" -M, --max-connection-age SEC maximum time a connection will stay\n"
" open is SEC seconds (default is %d)\n"
" -P, --proxy HOSTNAME[:PORT] use a HTTP proxy (default port is %d)\n"
" -s, --stdin-stdout use stdin/stdout for communication\n"
" (implies --no-daemon)\n"
" -S, --strict-content-length always write Content-Length bytes in requests\n"
" -T, --timeout TIME timeout, in milliseconds, before sending\n"
" padding to a buffering proxy\n"
" -U, --user-agent STRING specify User-Agent value in HTTP requests\n"
" -V, --version output version information and exit\n"
" -w, --no-daemon don't fork into the background\n"
"\n"
"Report bugs to %s.\n",
me, DEFAULT_HOST_PORT, DEFAULT_KEEP_ALIVE,
DEFAULT_MAX_CONNECTION_AGE, DEFAULT_PROXY_PORT,
BUG_REPORT_EMAIL);
}
 
static int
wait_for_connection_on_socket (int s)
{
struct sockaddr addr;
socklen_t len;
int t;
 
len = sizeof addr;
t = accept (s, &addr, &len);
if (t == -1)
return -1;
 
return t;
}
 
static void
parse_arguments (int argc, char **argv, Arguments *arg)
{
int c;
 
/* defaults */
 
arg->me = argv[0];
arg->device = NULL;
arg->forward_port = -1;
arg->host_name = NULL;
arg->host_port = DEFAULT_HOST_PORT;
arg->proxy_name = NO_PROXY;
arg->proxy_port = DEFAULT_PROXY_PORT;
arg->proxy_buffer_size = NO_PROXY_BUFFER;
arg->proxy_buffer_timeout = -1;
arg->content_length = DEFAULT_CONTENT_LENGTH;
arg->use_std = FALSE;
arg->use_daemon = TRUE;
arg->strict_content_length = FALSE;
arg->keep_alive = DEFAULT_KEEP_ALIVE;
arg->max_connection_age = DEFAULT_CONNECTION_MAX_TIME;
arg->proxy_authorization = NULL;
arg->user_agent = NULL;
 
for (;;)
{
int option_index = 0;
static struct option long_options[] =
{
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V' },
{ "no-daemon", no_argument, 0, 'w' },
{ "stdin-stdout", no_argument, 0, 's' },
#ifdef DEBUG_MODE
{ "debug", required_argument, 0, 'D' },
{ "logfile", required_argument, 0, 'l' },
#endif
{ "proxy", required_argument, 0, 'P' },
{ "device", required_argument, 0, 'd' },
{ "timeout", required_argument, 0, 'T' },
{ "keep-alive", required_argument, 0, 'k' },
{ "user-agent", required_argument, 0, 'U' },
{ "forward-port", required_argument, 0, 'F' },
{ "content-length", required_argument, 0, 'c' },
{ "strict-content-length", no_argument, 0, 'S' },
{ "proxy-buffer-size", required_argument, 0, 'B' },
{ "proxy-authorization", required_argument, 0, 'A' },
{ "max-connection-age", required_argument, 0, 'M' },
{ "proxy-authorization-file", required_argument, 0, 'z' },
{ 0, 0, 0, 0 }
};
 
static const char *short_options = "A:B:c:d:F:hk:M:P:sST:U:Vwz:"
#ifdef DEBUG_MODE
"D:l:"
#endif
;
 
c = getopt_long (argc, argv, short_options,
long_options, &option_index);
if (c == -1)
break;
 
switch (c)
{
case 0:
fprintf (stderr, "option %s", long_options[option_index].name);
if (optarg)
fprintf (stderr, " with arg %s", optarg);
fprintf (stderr, "\n");
break;
 
case 'A':
arg->proxy_authorization = optarg;
break;
 
case 'B':
arg->proxy_buffer_size = atoi_with_postfix (optarg);
break;
 
case 'c':
arg->content_length = atoi_with_postfix (optarg);
break;
 
case 'd':
arg->device = optarg;
break;
 
#ifdef DEBUG_MODE
case 'D':
if (optarg)
debug_level = atoi (optarg);
else
debug_level = 1;
break;
 
case 'l':
debug_file = fopen (optarg, "w");
if (debug_file == NULL)
{
fprintf (stderr, "%s: couldn't open file %s for writing\n",
arg->me, optarg);
exit (1);
}
break;
#endif
 
case 'F':
arg->forward_port = atoi (optarg);
break;
 
case 'k':
arg->keep_alive = atoi (optarg);
break;
 
case 'M':
arg->max_connection_age = atoi (optarg);
break;
 
case 'h':
usage (stdout, arg->me);
exit (0);
 
case 'P':
name_and_port (optarg, &arg->proxy_name, &arg->proxy_port);
if (arg->proxy_port == -1)
arg->proxy_port = DEFAULT_PROXY_PORT;
if (arg->proxy_buffer_timeout == -1)
arg->proxy_buffer_timeout = DEFAULT_PROXY_BUFFER_TIMEOUT;
break;
 
case 's':
arg->use_std=TRUE;
arg->use_daemon=FALSE;
break;
 
case 'S':
arg->strict_content_length = TRUE;
break;
 
case 'T':
arg->proxy_buffer_timeout = atoi (optarg);
break;
 
case 'U':
arg->user_agent = optarg;
break;
 
case 'V':
printf ("htc (%s) %s\n", PACKAGE, VERSION);
exit (0);
 
case 'w':
arg->use_daemon=FALSE;
break;
 
case 'z':
{
struct stat s;
char *auth;
int f;
 
f = open (optarg, O_RDONLY);
if (f == -1)
{
fprintf (stderr, "couldn't open %s: %s\n", optarg, strerror (errno));
exit (1);
}
 
if (fstat (f, &s) == -1)
{
fprintf (stderr, "error fstating %s: %s\n", optarg, strerror (errno));
exit (1);
}
 
auth = malloc (s.st_size + 1);
if (auth == NULL)
{
fprintf (stderr, "out of memory whilst allocating "
"authentication string\n");
exit (1);
}
 
if (read_all (f, auth, s.st_size) == -1)
{
fprintf (stderr, "error reading %s: %s\n", optarg, strerror (errno));
exit (1);
}
 
/*
* If file ends with a "\r\n" or "\n", chop them off.
*/
if (s.st_size >= 1 && auth[s.st_size - 1] == '\n')
{
s.st_size -=
(s.st_size >= 2 && auth[s.st_size - 2] == '\r') ? 2 : 1;
}
 
auth[s.st_size] = 0;
arg->proxy_authorization = auth;
}
break;
 
case '?':
break;
 
default:
fprintf (stderr, "?? getopt returned character code 0%o ??\n", c);
}
}
 
if (optind == argc - 1)
{
name_and_port (argv[optind], &arg->host_name, &arg->host_port);
if (arg->host_port == -1)
arg->host_port = DEFAULT_HOST_PORT;
}
else
{
fprintf (stderr, "%s: the destination of the tunnel must be specified.\n"
"%s: try '%s --help' for help.\n",
arg->me, arg->me, arg->me);
exit (1);
}
 
if (arg->device == NULL && arg->forward_port == -1 && !arg->use_std)
{
fprintf (stderr, "%s: one of --device, --forward-port or --stdin-stdout must be used.\n"
"%s: try '%s -help' for help.\n",
arg->me, arg->me, arg->me);
exit (1);
}
 
if ((arg->device != NULL && arg->forward_port != -1) ||
(arg->device != NULL && arg->use_std) ||
(arg->forward_port != -1 && arg->use_std))
{
fprintf (stderr, "%s: only one of --device, --forward-port or --stdin-stdout can be used.\n"
"%s: try '%s --help' for help.\n",
arg->me, arg->me, arg->me);
exit (1);
}
 
/* Removed test ((arg->device == NULL) == (arg->forward_port == -1))
* by Sampo Niskanen - those have been tested already! */
if (arg->host_name == NULL ||
arg->host_port == -1 ||
(arg->proxy_name != NO_PROXY && arg->proxy_port == -1))
{
usage (stderr, arg->me);
exit (1);
}
 
if (debug_level == 0 && debug_file != NULL)
{
fprintf (stderr, "%s: --logfile can't be used without debugging\n",
arg->me);
exit (1);
}
 
if (arg->proxy_name == NO_PROXY)
{
if (arg->proxy_buffer_size != NO_PROXY_BUFFER)
{
fprintf (stderr, "%s: warning: --proxy-buffer-size can't be "
"used without --proxy\n", arg->me);
arg->proxy_buffer_size = NO_PROXY_BUFFER;
}
 
if (arg->proxy_buffer_timeout != -1)
{
fprintf (stderr, "%s: warning: --proxy-buffer-timeout can't be "
"used without --proxy\n", arg->me);
arg->proxy_buffer_timeout = -1;
}
 
if (arg->proxy_authorization != NULL)
{
fprintf (stderr, "%s: warning: --proxy-authorization can't be "
"used without --proxy\n", arg->me);
arg->proxy_authorization = NULL;
}
}
else if (arg->proxy_buffer_size == NO_PROXY_BUFFER)
arg->proxy_buffer_timeout = -1;
}
 
int
main (int argc, char **argv)
{
int s = -1;
int fd = -1;
Arguments arg;
Tunnel *tunnel;
int closed;
 
parse_arguments (argc, argv, &arg);
 
if ((debug_level == 0 || debug_file != NULL) && arg.use_daemon)
daemon (0, 1);
 
#ifdef DEBUG_MODE
if (debug_level != 0 && debug_file == NULL)
debug_file = stderr;
#else
openlog ("htc", LOG_PID, LOG_DAEMON);
#endif
 
log_notice ("htc (%s) %s started with arguments:", PACKAGE, VERSION);
log_notice (" me = %s", arg.me);
log_notice (" device = %s", arg.device ? arg.device : "(null)");
log_notice (" host_name = %s", arg.host_name ? arg.host_name : "(null)");
log_notice (" host_port = %d", arg.host_port);
log_notice (" proxy_name = %s", arg.proxy_name ? arg.proxy_name : "(null)");
log_notice (" proxy_port = %d", arg.proxy_port);
log_notice (" proxy_buffer_size = %d", arg.proxy_buffer_size);
log_notice (" proxy_buffer_timeout = %d", arg.proxy_buffer_timeout);
log_notice (" content_length = %d", arg.content_length);
log_notice (" forward_port = %d", arg.forward_port);
log_notice (" max_connection_age = %d", arg.max_connection_age);
log_notice (" use_std = %d", arg.use_std);
log_notice (" strict_content_length = %d", arg.strict_content_length);
log_notice (" keep_alive = %d", arg.keep_alive);
log_notice (" proxy_authorization = %s",
arg.proxy_authorization ? arg.proxy_authorization : "(null)");
log_notice (" user_agent = %s", arg.user_agent ? arg.user_agent : "(null)");
log_notice (" debug_level = %d", debug_level);
 
 
if (arg.forward_port != -1)
{
struct in_addr addr;
 
addr.s_addr = INADDR_ANY;
s = server_socket (addr, arg.forward_port, 0);
log_debug ("server_socket (%d) = %d", arg.forward_port, s);
if (s == -1)
{
log_error ("couldn't create server socket: %s", strerror (errno));
log_exit (1);
}
}
 
#ifdef DEBUG_MODE
signal (SIGPIPE, log_sigpipe);
#else
signal (SIGPIPE, SIG_IGN);
#endif
 
for (;;)
{
time_t last_tunnel_write;
 
if (arg.device)
{
fd = open_device (arg.device);
log_debug ("open_device (\"%s\") = %d", arg.device, fd);
if (fd == -1)
{
log_error ("couldn't open %s: %s",
arg.device, strerror (errno));
log_exit (1);
}
/* Check that fd is not 0 (clash with --stdin-stdout) */
if (fd == 0)
{
log_notice("changing fd from %d to 3",fd);
if (dup2(fd,3) != 3)
{
log_error ("couldn't dup2(%d,3): %s",fd,strerror(errno));
log_exit (1);
}
}
}
else if (arg.forward_port != -1)
{
log_debug ("waiting for connection on port %d", arg.forward_port);
fd = wait_for_connection_on_socket (s);
log_debug ("wait_for_connection_on_socket (%d) = %d", s, fd);
if (fd == -1)
{
log_error ("couldn't forward port %d: %s",
arg.forward_port, strerror (errno));
log_exit (1);
}
/* Check that fd is not 0 (clash with --stdin-stdout) */
if (fd == 0)
{
log_notice("changing fd from %d to 3",fd);
if (dup2(fd,3) != 3)
{
log_error ("couldn't dup2(%d,3): %s",fd,strerror(errno));
log_exit (1);
}
}
} else if (arg.use_std) {
log_debug ("using stdin as fd");
fd = 0;
if (fcntl(fd,F_SETFL,O_NONBLOCK)==-1)
{
log_error ("couldn't set stdin to non-blocking mode: %s",
strerror(errno));
log_exit (1);
}
/* Usage of stdout (fd = 1) is checked later. */
}
 
log_debug ("creating a new tunnel");
tunnel = tunnel_new_client (arg.host_name, arg.host_port,
arg.proxy_name, arg.proxy_port,
arg.content_length);
if (tunnel == NULL)
{
log_error ("couldn't create tunnel");
log_exit (1);
}
 
if (tunnel_setopt (tunnel, "strict_content_length",
&arg.strict_content_length) == -1)
log_debug ("tunnel_setopt strict_content_length error: %s",
strerror (errno));
 
if (tunnel_setopt (tunnel, "keep_alive",
&arg.keep_alive) == -1)
log_debug ("tunnel_setopt keep_alive error: %s", strerror (errno));
 
if (tunnel_setopt (tunnel, "max_connection_age",
&arg.max_connection_age) == -1)
log_debug ("tunnel_setopt max_connection_age error: %s",
strerror (errno));
 
if (arg.proxy_authorization != NULL)
{
ssize_t len;
char *auth;
 
len = encode_base64 (arg.proxy_authorization,
strlen (arg.proxy_authorization),
&auth);
if (len == -1)
{
log_error ("encode_base64 error: %s", strerror (errno));
}
else
{
char *str = malloc (len + 7);
 
if (str == NULL)
{
log_error ("out of memory when encoding "
"authorization string");
log_exit (1);
}
 
strcpy (str, "Basic ");
strcat (str, auth);
free (auth);
if (tunnel_setopt (tunnel, "proxy_authorization", str) == -1)
log_error ("tunnel_setopt proxy_authorization error: %s",
strerror (errno));
 
free (str);
}
}
 
if (arg.user_agent != NULL)
{
if (tunnel_setopt (tunnel, "user_agent", arg.user_agent) == -1)
log_error ("tunnel_setopt user_agent error: %s",
strerror (errno));
}
 
if (tunnel_connect (tunnel) == -1)
{
log_error ("couldn't open tunnel: %s", strerror (errno));
log_exit (1);
}
if (arg.proxy_name)
log_notice ("connected to %s:%d via %s:%d",
arg.host_name, arg.host_port,
arg.proxy_name, arg.proxy_port);
else
log_notice ("connected to %s:%d", arg.host_name, arg.host_port);
 
closed = FALSE;
time (&last_tunnel_write);
while (!closed)
{
struct pollfd pollfd[2];
int keep_alive_timeout;
int timeout;
time_t t;
int n;
 
pollfd[0].fd = fd;
pollfd[0].events = POLLIN;
pollfd[1].fd = tunnel_pollin_fd (tunnel);
pollfd[1].events = POLLIN;
time (&t);
timeout = 1000 * (arg.keep_alive - (t - last_tunnel_write));
keep_alive_timeout = TRUE;
if (timeout < 0)
timeout = 0;
if (arg.proxy_buffer_timeout != -1 &&
arg.proxy_buffer_timeout < timeout)
{
timeout = arg.proxy_buffer_timeout;
keep_alive_timeout = FALSE;
}
 
log_annoying ("poll () ...");
n = poll (pollfd, 2, timeout);
log_annoying ("... = %d", n);
if (n == -1)
{
log_error ("poll error: %s", strerror (errno));
log_exit (1);
}
else if (n == 0)
{
log_verbose ("poll() timed out");
if (keep_alive_timeout)
{
tunnel_padding (tunnel, 1);
time (&last_tunnel_write);
}
else
{
if (tunnel_maybe_pad (tunnel, arg.proxy_buffer_size) > 0)
time (&last_tunnel_write);
}
continue;
}
handle_input ("device or port", tunnel, fd, pollfd[0].revents,
handle_device_input, &closed);
handle_input ("tunnel", tunnel, fd, pollfd[1].revents,
handle_tunnel_input, &closed);
 
if (pollfd[0].revents & POLLIN)
time (&last_tunnel_write);
}
 
log_debug ("destroying tunnel");
if (fd != 0)
{
close (fd);
}
tunnel_destroy (tunnel);
if (arg.proxy_name)
log_notice ("disconnected from %s:%d via %s:%d",
arg.host_name, arg.host_port,
arg.proxy_name, arg.proxy_port);
else
log_notice ("disconnected from %s%d", arg.host_name, arg.host_port);
}
 
log_debug ("closing server socket");
close (s);
 
log_exit (0);
}
New file
/httptunnel/http.c
@@ -0,0 +1,854 @@
/*
http.c
Copyright (C) 1999 Lars Brinkhoff. See COPYING for terms and conditions.
 
bug alert: parse_header() doesn't handle header fields that are extended
over multiple lines.
*/
 
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include "http.h"
#include "common.h"
 
static inline ssize_t
http_method (int fd, Http_destination *dest,
Http_method method, ssize_t length)
{
char str[1024]; /* FIXME: possible buffer overflow */
Http_request *request;
ssize_t n;
 
if (fd == -1)
{
log_error ("http_method: fd == -1");
return -1;
}
 
n = 0;
if (dest->proxy_name != NULL)
n = sprintf (str, "http://%s:%d", dest->host_name, dest->host_port);
sprintf (str + n, "/index.html?crap=%ld", time (NULL));
 
request = http_create_request (method, str, 1, 1);
if (request == NULL)
return -1;
 
sprintf (str, "%s:%d", dest->host_name, dest->host_port);
http_add_header (&request->header, "Host", str);
 
if (length >= 0)
{
sprintf (str, "%d", length);
http_add_header (&request->header, "Content-Length", str);
}
 
http_add_header (&request->header, "Connection", "close");
 
if (dest->proxy_authorization)
{
http_add_header (&request->header,
"Proxy-Authorization",
dest->proxy_authorization);
}
 
if (dest->user_agent)
{
http_add_header (&request->header,
"User-Agent",
dest->user_agent);
}
 
n = http_write_request (fd, request);
http_destroy_request (request);
return n;
}
 
ssize_t
http_get (int fd, Http_destination *dest)
{
return http_method (fd, dest, HTTP_GET, -1);
}
 
ssize_t
http_put (int fd, Http_destination *dest, size_t length)
{
return http_method (fd, dest, HTTP_PUT, (ssize_t)length);
}
 
ssize_t
http_post (int fd, Http_destination *dest, size_t length)
{
return http_method (fd, dest, HTTP_POST, (ssize_t)length);
}
 
int
http_error_to_errno (int err)
{
/* Error codes taken from RFC2068. */
switch (err)
{
case -1: /* system error */
return errno;
case -200: /* OK */
case -201: /* Created */
case -202: /* Accepted */
case -203: /* Non-Authoritative Information */
case -204: /* No Content */
case -205: /* Reset Content */
case -206: /* Partial Content */
return 0;
case -400: /* Bad Request */
log_error ("http_error_to_errno: 400 bad request");
return EIO;
case -401: /* Unauthorized */
log_error ("http_error_to_errno: 401 unauthorized");
return EACCES;
case -403: /* Forbidden */
log_error ("http_error_to_errno: 403 forbidden");
return EACCES;
case -404: /* Not Found */
log_error ("http_error_to_errno: 404 not found");
return ENOENT;
case -411: /* Length Required */
log_error ("http_error_to_errno: 411 length required");
return EIO;
case -413: /* Request Entity Too Large */
log_error ("http_error_to_errno: 413 request entity too large");
return EIO;
case -505: /* HTTP Version Not Supported */
log_error ("http_error_to_errno: 413 HTTP version not supported");
return EIO;
case -100: /* Continue */
case -101: /* Switching Protocols */
case -300: /* Multiple Choices */
case -301: /* Moved Permanently */
case -302: /* Moved Temporarily */
case -303: /* See Other */
case -304: /* Not Modified */
case -305: /* Use Proxy */
case -402: /* Payment Required */
case -405: /* Method Not Allowed */
case -406: /* Not Acceptable */
case -407: /* Proxy Autentication Required */
case -408: /* Request Timeout */
case -409: /* Conflict */
case -410: /* Gone */
case -412: /* Precondition Failed */
case -414: /* Request-URI Too Long */
case -415: /* Unsupported Media Type */
case -500: /* Internal Server Error */
case -501: /* Not Implemented */
case -502: /* Bad Gateway */
case -503: /* Service Unavailable */
case -504: /* Gateway Timeout */
log_error ("http_error_to_errno: HTTP error %d", err);
return EIO;
default:
log_error ("http_error_to_errno: unknown error %d", err);
return EIO;
}
}
 
static Http_method
http_string_to_method (const char *method, size_t n)
{
if (strncmp (method, "GET", n) == 0)
return HTTP_GET;
if (strncmp (method, "PUT", n) == 0)
return HTTP_PUT;
if (strncmp (method, "POST", n) == 0)
return HTTP_POST;
if (strncmp (method, "OPTIONS", n) == 0)
return HTTP_OPTIONS;
if (strncmp (method, "HEAD", n) == 0)
return HTTP_HEAD;
if (strncmp (method, "DELETE", n) == 0)
return HTTP_DELETE;
if (strncmp (method, "TRACE", n) == 0)
return HTTP_TRACE;
return -1;
}
 
static const char *
http_method_to_string (Http_method method)
{
switch (method)
{
case HTTP_GET: return "GET";
case HTTP_PUT: return "PUT";
case HTTP_POST: return "POST";
case HTTP_OPTIONS: return "OPTIONS";
case HTTP_HEAD: return "HEAD";
case HTTP_DELETE: return "DELETE";
case HTTP_TRACE: return "TRACE";
}
return "(uknown)";
}
 
static ssize_t
read_until (int fd, int ch, unsigned char **data)
{
unsigned char *buf, *buf2;
ssize_t n, len, buf_size;
 
*data = NULL;
 
buf_size = 100;
buf = malloc (buf_size);
if (buf == NULL)
{
log_error ("read_until: out of memory");
return -1;
}
 
len = 0;
while ((n = read_all (fd, buf + len, 1)) == 1)
{
if (buf[len++] == ch)
break;
if (len + 1 == buf_size)
{
buf_size *= 2;
buf2 = realloc (buf, buf_size);
if (buf2 == NULL)
{
log_error ("read_until: realloc failed");
free (buf);
return -1;
}
buf = buf2;
}
}
if (n <= 0)
{
free (buf);
if (n == 0)
log_error ("read_until: closed");
else
log_error ("read_until: read error: %s", strerror (errno));
return n;
}
 
/* Shrink to minimum size + 1 in case someone wants to add a NUL. */
buf2 = realloc (buf, len + 1);
if (buf2 == NULL)
log_error ("read_until: realloc: shrink failed"); /* not fatal */
else
buf = buf2;
 
*data = buf;
return len;
}
 
static inline Http_header *
http_alloc_header (const char *name, const char *value)
{
Http_header *header;
 
header = malloc (sizeof (Http_header));
if (header == NULL)
return NULL;
 
header->name = header->value = NULL;
header->name = strdup (name);
header->value = strdup (value);
if (name == NULL || value == NULL)
{
if (name == NULL)
free ((char *)name);
if (value == NULL)
free ((char *)value);
free (header);
return NULL;
}
 
return header;
}
 
Http_header *
http_add_header (Http_header **header, const char *name, const char *value)
{
Http_header *new_header;
 
new_header = http_alloc_header (name, value);
if (new_header == NULL)
return NULL;
 
new_header->next = NULL;
while (*header)
header = &(*header)->next;
*header = new_header;
 
return new_header;
}
 
static ssize_t
parse_header (int fd, Http_header **header)
{
unsigned char buf[2];
unsigned char *data;
Http_header *h;
size_t len;
ssize_t n;
 
*header = NULL;
 
n = read_all (fd, buf, 2);
if (n <= 0)
return n;
if (buf[0] == '\r' && buf[1] == '\n')
return n;
 
h = malloc (sizeof (Http_header));
if (h == NULL)
{
log_error ("parse_header: malloc failed");
return -1;
}
*header = h;
h->name = NULL;
h->value = NULL;
 
n = read_until (fd, ':', &data);
if (n <= 0)
return n;
data = realloc (data, n + 2);
if (data == NULL)
{
log_error ("parse_header: realloc failed");
return -1;
}
memmove (data + 2, data, n);
memcpy (data, buf, 2);
n += 2;
data[n - 1] = 0;
h->name = data;
len = n;
 
n = read_until (fd, '\r', &data);
if (n <= 0)
return n;
data[n - 1] = 0;
h->value = data;
len += n;
 
n = read_until (fd, '\n', &data);
if (n <= 0)
return n;
free (data);
if (n != 1)
{
log_error ("parse_header: invalid line ending");
return -1;
}
len += n;
 
log_verbose ("parse_header: %s:%s", h->name, h->value);
 
n = parse_header (fd, &h->next);
if (n <= 0)
return n;
len += n;
 
return len;
}
 
static ssize_t
http_write_header (int fd, Http_header *header)
{
ssize_t n = 0, m;
 
if (header == NULL)
return write_all (fd, "\r\n", 2);
 
m = write_all (fd, (void *)header->name, strlen (header->name));
if (m == -1)
{
return -1;
}
n += m;
 
m = write_all (fd, ": ", 2);
if (m == -1)
{
return -1;
}
n += m;
 
m = write_all (fd, (void *)header->value, strlen (header->value));
if (m == -1)
{
return -1;
}
n += m;
 
m = write_all (fd, "\r\n", 2);
if (m == -1)
{
return -1;
}
n += m;
 
m = http_write_header (fd, header->next);
if (m == -1)
{
return -1;
}
n += m;
 
return n;
}
 
static void
http_destroy_header (Http_header *header)
{
if (header == NULL)
return;
 
http_destroy_header (header->next);
 
if (header->name)
free ((char *)header->name);
if (header->value)
free ((char *)header->value);
free (header);
}
 
static inline Http_response *
http_allocate_response (const char *status_message)
{
Http_response *response;
 
response = malloc (sizeof (Http_response));
if (response == NULL)
return NULL;
 
response->status_message = strdup (status_message);
if (response->status_message == NULL)
{
free (response);
return NULL;
}
 
return response;
}
 
Http_response *
http_create_response (int major_version,
int minor_version,
int status_code,
const char *status_message)
{
Http_response *response;
 
response = http_allocate_response (status_message);
if (response == NULL)
return NULL;
 
response->major_version = major_version;
response->minor_version = minor_version;
response->status_code = status_code;
response->header = NULL;
 
return response;
}
 
ssize_t
http_parse_response (int fd, Http_response **response_)
{
Http_response *response;
unsigned char *data;
size_t len;
ssize_t n;
 
*response_ = NULL;
 
response = malloc (sizeof (Http_response));
if (response == NULL)
{
log_error ("http_parse_response: out of memory");
return -1;
}
 
response->major_version = -1;
response->minor_version = -1;
response->status_code = -1;
response->status_message = NULL;
response->header = NULL;
 
n = read_until (fd, '/', &data);
if (n <= 0)
{
free (response);
return n;
}
else if (n != 5 || memcmp (data, "HTTP", 4) != 0)
{
log_error ("http_parse_response: expected \"HTTP\"");
free (data);
free (response);
return -1;
}
free (data);
len = n;
 
n = read_until (fd, '.', &data);
if (n <= 0)
{
free (response);
return n;
}
data[n - 1] = 0;
response->major_version = atoi (data);
log_verbose ("http_parse_response: major version = %d",
response->major_version);
free (data);
len += n;
 
n = read_until (fd, ' ', &data);
if (n <= 0)
{
free (response);
return n;
}
data[n - 1] = 0;
response->minor_version = atoi (data);
log_verbose ("http_parse_response: minor version = %d",
response->minor_version);
free (data);
len += n;
 
n = read_until (fd, ' ', &data);
if (n <= 0)
{
free (response);
return n;
}
data[n - 1] = 0;
response->status_code = atoi (data);
log_verbose ("http_parse_response: status code = %d",
response->status_code);
free (data);
len += n;
 
n = read_until (fd, '\r', &data);
if (n <= 0)
{
free (response);
return n;
}
data[n - 1] = 0;
response->status_message = data;
log_verbose ("http_parse_response: status message = \"%s\"",
response->status_message);
len += n;
 
n = read_until (fd, '\n', &data);
if (n <= 0)
{
http_destroy_response (response);
return n;
}
free (data);
if (n != 1)
{
log_error ("http_parse_request: invalid line ending");
http_destroy_response (response);
return -1;
}
len += n;
 
n = parse_header (fd, &response->header);
if (n <= 0)
{
http_destroy_response (response);
return n;
}
len += n;
 
*response_ = response;
return len;
}
 
void
http_destroy_response (Http_response *response)
{
if (response->status_message)
free ((char *)response->status_message);
http_destroy_header (response->header);
free (response);
}
 
static inline Http_request *
http_allocate_request (const char *uri)
{
Http_request *request;
 
request = malloc (sizeof (Http_request));
if (request == NULL)
return NULL;
 
request->uri = strdup (uri);
if (request->uri == NULL)
{
free (request);
return NULL;
}
 
return request;
}
 
Http_request *
http_create_request (Http_method method,
const char *uri,
int major_version,
int minor_version)
{
Http_request *request;
 
request = http_allocate_request (uri);
if (request == NULL)
return NULL;
 
request->method = method;
request->major_version = major_version;
request->minor_version = minor_version;
request->header = NULL;
 
return request;
}
 
ssize_t
http_parse_request (int fd, Http_request **request_)
{
Http_request *request;
unsigned char *data;
size_t len;
ssize_t n;
 
*request_ = NULL;
 
request = malloc (sizeof (Http_request));
if (request == NULL)
{
log_error ("http_parse_request: out of memory");
return -1;
}
 
request->method = -1;
request->uri = NULL;
request->major_version = -1;
request->minor_version = -1;
request->header = NULL;
 
n = read_until (fd, ' ', &data);
if (n <= 0)
{
free (request);
return n;
}
request->method = http_string_to_method (data, n - 1);
if (request->method == -1)
{
log_error ("http_parse_request: expected an HTTP method");
free (data);
free (request);
return -1;
}
data[n - 1] = 0;
log_verbose ("http_parse_request: method = \"%s\"", data);
free (data);
len = n;
 
n = read_until (fd, ' ', &data);
if (n <= 0)
{
free (request);
return n;
}
data[n - 1] = 0;
request->uri = data;
len += n;
log_verbose ("http_parse_request: uri = \"%s\"", request->uri);
 
n = read_until (fd, '/', &data);
if (n <= 0)
{
http_destroy_request (request);
return n;
}
else if (n != 5 || memcmp (data, "HTTP", 4) != 0)
{
log_error ("http_parse_request: expected \"HTTP\"");
free (data);
http_destroy_request (request);
return -1;
}
free (data);
len = n;
 
n = read_until (fd, '.', &data);
if (n <= 0)
{
http_destroy_request (request);
return n;
}
data[n - 1] = 0;
request->major_version = atoi (data);
log_verbose ("http_parse_request: major version = %d",
request->major_version);
free (data);
len += n;
 
n = read_until (fd, '\r', &data);
if (n <= 0)
{
http_destroy_request (request);
return n;
}
data[n - 1] = 0;
request->minor_version = atoi (data);
log_verbose ("http_parse_request: minor version = %d",
request->minor_version);
free (data);
len += n;
 
n = read_until (fd, '\n', &data);
if (n <= 0)
{
http_destroy_request (request);
return n;
}
free (data);
if (n != 1)
{
log_error ("http_parse_request: invalid line ending");
http_destroy_request (request);
return -1;
}
len += n;
 
n = parse_header (fd, &request->header);
if (n <= 0)
{
http_destroy_request (request);
return n;
}
len += n;
 
*request_ = request;
return len;
}
 
ssize_t
http_write_request (int fd, Http_request *request)
{
char str[1024]; /* FIXME: buffer overflow */
ssize_t n = 0;
size_t m;
m = sprintf (str, "%s %s HTTP/%d.%d\r\n",
http_method_to_string (request->method),
request->uri,
request->major_version,
request->minor_version);
m = write_all (fd, str, m);
log_verbose ("http_write_request: %s", str);
if (m == -1)
{
log_error ("http_write_request: write error: %s", strerror (errno));
return -1;
}
n += m;
 
m = http_write_header (fd, request->header);
if (m == -1)
{
return -1;
}
n += m;
 
return n;
}
 
void
http_destroy_request (Http_request *request)
{
if (request->uri)
free ((char *)request->uri);
http_destroy_header (request->header);
free (request);
}
 
static Http_header *
http_header_find (Http_header *header, const char *name)
{
if (header == NULL)
return NULL;
 
if (strcmp (header->name, name) == 0)
return header;
 
return http_header_find (header->next, name);
}
 
const char *
http_header_get (Http_header *header, const char *name)
{
Http_header *h;
 
h = http_header_find (header, name);
if (h == NULL)
return NULL;
 
return h->value;
}
 
#if 0
void
http_header_set (Http_header **header, const char *name, const char *value)
{
Http_header *h;
size_t n;
char *v;
 
n = strlen (value);
v = malloc (n + 1);
if (v == NULL)
fail;
memcpy (v, value, n + 1);
 
h = http_header_find (*header, name);
if (h == NULL)
{
Http_header *h2;
 
h2 = malloc (sizeof (Http_header));
if (h2 == NULL)
fail;
 
n = strlen (name);
h2->name = malloc (strlen (name) + 1);
if (h2->name == NULL)
fail;
memcpy (h2->name, name, n + 1);
 
h2->value = v;
 
h2->next = *header;
 
*header = h2;
 
return NULL;
}
else
{
free (h->value);
h->value = v;
}
}
#endif
New file
/httptunnel/doc/rfc2068.txt
@@ -0,0 +1,9075 @@
 
 
 
 
 
 
Network Working Group R. Fielding
Request for Comments: 2068 UC Irvine
Category: Standards Track J. Gettys
J. Mogul
DEC
H. Frystyk
T. Berners-Lee
MIT/LCS
January 1997
 
 
Hypertext Transfer Protocol -- HTTP/1.1
 
Status of this Memo
 
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
Official Protocol Standards" (STD 1) for the standardization state
and status of this protocol. Distribution of this memo is unlimited.
 
Abstract
 
The Hypertext Transfer Protocol (HTTP) is an application-level
protocol for distributed, collaborative, hypermedia information
systems. It is a generic, stateless, object-oriented protocol which
can be used for many tasks, such as name servers and distributed
object management systems, through extension of its request methods.
A feature of HTTP is the typing and negotiation of data
representation, allowing systems to be built independently of the
data being transferred.
 
HTTP has been in use by the World-Wide Web global information
initiative since 1990. This specification defines the protocol
referred to as "HTTP/1.1".
 
Table of Contents
 
1 Introduction.............................................7
1.1 Purpose ..............................................7
1.2 Requirements .........................................7
1.3 Terminology ..........................................8
1.4 Overall Operation ...................................11
2 Notational Conventions and Generic Grammar..............13
2.1 Augmented BNF .......................................13
2.2 Basic Rules .........................................15
3 Protocol Parameters.....................................17
3.1 HTTP Version ........................................17
 
 
 
Fielding, et. al. Standards Track [Page 1]
RFC 2068 HTTP/1.1 January 1997
 
 
3.2 Uniform Resource Identifiers ........................18
3.2.1 General Syntax ...................................18
3.2.2 http URL .........................................19
3.2.3 URI Comparison ...................................20
3.3 Date/Time Formats ...................................21
3.3.1 Full Date ........................................21
3.3.2 Delta Seconds ....................................22
3.4 Character Sets ......................................22
3.5 Content Codings .....................................23
3.6 Transfer Codings ....................................24
3.7 Media Types .........................................25
3.7.1 Canonicalization and Text Defaults ...............26
3.7.2 Multipart Types ..................................27
3.8 Product Tokens ......................................28
3.9 Quality Values ......................................28
3.10 Language Tags ......................................28
3.11 Entity Tags ........................................29
3.12 Range Units ........................................30
4 HTTP Message............................................30
4.1 Message Types .......................................30
4.2 Message Headers .....................................31
4.3 Message Body ........................................32
4.4 Message Length ......................................32
4.5 General Header Fields ...............................34
5 Request.................................................34
5.1 Request-Line ........................................34
5.1.1 Method ...........................................35
5.1.2 Request-URI ......................................35
5.2 The Resource Identified by a Request ................37
5.3 Request Header Fields ...............................37
6 Response................................................38
6.1 Status-Line .........................................38
6.1.1 Status Code and Reason Phrase ....................39
6.2 Response Header Fields ..............................41
7 Entity..................................................41
7.1 Entity Header Fields ................................41
7.2 Entity Body .........................................42
7.2.1 Type .............................................42
7.2.2 Length ...........................................43
8 Connections.............................................43
8.1 Persistent Connections ..............................43
8.1.1 Purpose ..........................................43
8.1.2 Overall Operation ................................44
8.1.3 Proxy Servers ....................................45
8.1.4 Practical Considerations .........................45
8.2 Message Transmission Requirements ...................46
9 Method Definitions......................................48
9.1 Safe and Idempotent Methods .........................48
 
 
 
Fielding, et. al. Standards Track [Page 2]
RFC 2068 HTTP/1.1 January 1997
 
 
9.1.1 Safe Methods .....................................48
9.1.2 Idempotent Methods ...............................49
9.2 OPTIONS .............................................49
9.3 GET .................................................50
9.4 HEAD ................................................50
9.5 POST ................................................51
9.6 PUT .................................................52
9.7 DELETE ..............................................53
9.8 TRACE ...............................................53
10 Status Code Definitions................................53
10.1 Informational 1xx ..................................54
10.1.1 100 Continue ....................................54
10.1.2 101 Switching Protocols .........................54
10.2 Successful 2xx .....................................54
10.2.1 200 OK ..........................................54
10.2.2 201 Created .....................................55
10.2.3 202 Accepted ....................................55
10.2.4 203 Non-Authoritative Information ...............55
10.2.5 204 No Content ..................................55
10.2.6 205 Reset Content ...............................56
10.2.7 206 Partial Content .............................56
10.3 Redirection 3xx ....................................56
10.3.1 300 Multiple Choices ............................57
10.3.2 301 Moved Permanently ...........................57
10.3.3 302 Moved Temporarily ...........................58
10.3.4 303 See Other ...................................58
10.3.5 304 Not Modified ................................58
10.3.6 305 Use Proxy ...................................59
10.4 Client Error 4xx ...................................59
10.4.1 400 Bad Request .................................60
10.4.2 401 Unauthorized ................................60
10.4.3 402 Payment Required ............................60
10.4.4 403 Forbidden ...................................60
10.4.5 404 Not Found ...................................60
10.4.6 405 Method Not Allowed ..........................61
10.4.7 406 Not Acceptable ..............................61
10.4.8 407 Proxy Authentication Required ...............61
10.4.9 408 Request Timeout .............................62
10.4.10 409 Conflict ...................................62
10.4.11 410 Gone .......................................62
10.4.12 411 Length Required ............................63
10.4.13 412 Precondition Failed ........................63
10.4.14 413 Request Entity Too Large ...................63
10.4.15 414 Request-URI Too Long .......................63
10.4.16 415 Unsupported Media Type .....................63
10.5 Server Error 5xx ...................................64
10.5.1 500 Internal Server Error .......................64
10.5.2 501 Not Implemented .............................64
 
 
 
Fielding, et. al. Standards Track [Page 3]
RFC 2068 HTTP/1.1 January 1997
 
 
10.5.3 502 Bad Gateway .................................64
10.5.4 503 Service Unavailable .........................64
10.5.5 504 Gateway Timeout .............................64
10.5.6 505 HTTP Version Not Supported ..................65
11 Access Authentication..................................65
11.1 Basic Authentication Scheme ........................66
11.2 Digest Authentication Scheme .......................67
12 Content Negotiation....................................67
12.1 Server-driven Negotiation ..........................68
12.2 Agent-driven Negotiation ...........................69
12.3 Transparent Negotiation ............................70
13 Caching in HTTP........................................70
13.1.1 Cache Correctness ...............................72
13.1.2 Warnings ........................................73
13.1.3 Cache-control Mechanisms ........................74
13.1.4 Explicit User Agent Warnings ....................74
13.1.5 Exceptions to the Rules and Warnings ............75
13.1.6 Client-controlled Behavior ......................75
13.2 Expiration Model ...................................75
13.2.1 Server-Specified Expiration .....................75
13.2.2 Heuristic Expiration ............................76
13.2.3 Age Calculations ................................77
13.2.4 Expiration Calculations .........................79
13.2.5 Disambiguating Expiration Values ................80
13.2.6 Disambiguating Multiple Responses ...............80
13.3 Validation Model ...................................81
13.3.1 Last-modified Dates .............................82
13.3.2 Entity Tag Cache Validators .....................82
13.3.3 Weak and Strong Validators ......................82
13.3.4 Rules for When to Use Entity Tags and Last-
modified Dates..........................................85
13.3.5 Non-validating Conditionals .....................86
13.4 Response Cachability ...............................86
13.5 Constructing Responses From Caches .................87
13.5.1 End-to-end and Hop-by-hop Headers ...............88
13.5.2 Non-modifiable Headers ..........................88
13.5.3 Combining Headers ...............................89
13.5.4 Combining Byte Ranges ...........................90
13.6 Caching Negotiated Responses .......................90
13.7 Shared and Non-Shared Caches .......................91
13.8 Errors or Incomplete Response Cache Behavior .......91
13.9 Side Effects of GET and HEAD .......................92
13.10 Invalidation After Updates or Deletions ...........92
13.11 Write-Through Mandatory ...........................93
13.12 Cache Replacement .................................93
13.13 History Lists .....................................93
14 Header Field Definitions...............................94
14.1 Accept .............................................95
 
 
 
Fielding, et. al. Standards Track [Page 4]
RFC 2068 HTTP/1.1 January 1997
 
 
14.2 Accept-Charset .....................................97
14.3 Accept-Encoding ....................................97
14.4 Accept-Language ....................................98
14.5 Accept-Ranges ......................................99
14.6 Age ................................................99
14.7 Allow .............................................100
14.8 Authorization .....................................100
14.9 Cache-Control .....................................101
14.9.1 What is Cachable ...............................103
14.9.2 What May be Stored by Caches ...................103
14.9.3 Modifications of the Basic Expiration Mechanism 104
14.9.4 Cache Revalidation and Reload Controls .........105
14.9.5 No-Transform Directive .........................107
14.9.6 Cache Control Extensions .......................108
14.10 Connection .......................................109
14.11 Content-Base .....................................109
14.12 Content-Encoding .................................110
14.13 Content-Language .................................110
14.14 Content-Length ...................................111
14.15 Content-Location .................................112
14.16 Content-MD5 ......................................113
14.17 Content-Range ....................................114
14.18 Content-Type .....................................116
14.19 Date .............................................116
14.20 ETag .............................................117
14.21 Expires ..........................................117
14.22 From .............................................118
14.23 Host .............................................119
14.24 If-Modified-Since ................................119
14.25 If-Match .........................................121
14.26 If-None-Match ....................................122
14.27 If-Range .........................................123
14.28 If-Unmodified-Since ..............................124
14.29 Last-Modified ....................................124
14.30 Location .........................................125
14.31 Max-Forwards .....................................125
14.32 Pragma ...........................................126
14.33 Proxy-Authenticate ...............................127
14.34 Proxy-Authorization ..............................127
14.35 Public ...........................................127
14.36 Range ............................................128
14.36.1 Byte Ranges ...................................128
14.36.2 Range Retrieval Requests ......................130
14.37 Referer ..........................................131
14.38 Retry-After ......................................131
14.39 Server ...........................................132
14.40 Transfer-Encoding ................................132
14.41 Upgrade ..........................................132
 
 
 
Fielding, et. al. Standards Track [Page 5]
RFC 2068 HTTP/1.1 January 1997
 
 
14.42 User-Agent .......................................134
14.43 Vary .............................................134
14.44 Via ..............................................135
14.45 Warning ..........................................137
14.46 WWW-Authenticate .................................139
15 Security Considerations...............................139
15.1 Authentication of Clients .........................139
15.2 Offering a Choice of Authentication Schemes .......140
15.3 Abuse of Server Log Information ...................141
15.4 Transfer of Sensitive Information .................141
15.5 Attacks Based On File and Path Names ..............142
15.6 Personal Information ..............................143
15.7 Privacy Issues Connected to Accept Headers ........143
15.8 DNS Spoofing ......................................144
15.9 Location Headers and Spoofing .....................144
16 Acknowledgments.......................................144
17 References............................................146
18 Authors' Addresses....................................149
19 Appendices............................................150
19.1 Internet Media Type message/http ..................150
19.2 Internet Media Type multipart/byteranges ..........150
19.3 Tolerant Applications .............................151
19.4 Differences Between HTTP Entities and
MIME Entities...........................................152
19.4.1 Conversion to Canonical Form ...................152
19.4.2 Conversion of Date Formats .....................153
19.4.3 Introduction of Content-Encoding ...............153
19.4.4 No Content-Transfer-Encoding ...................153
19.4.5 HTTP Header Fields in Multipart Body-Parts .....153
19.4.6 Introduction of Transfer-Encoding ..............154
19.4.7 MIME-Version ...................................154
19.5 Changes from HTTP/1.0 .............................154
19.5.1 Changes to Simplify Multi-homed Web Servers and
Conserve IP Addresses .................................155
19.6 Additional Features ...............................156
19.6.1 Additional Request Methods .....................156
19.6.2 Additional Header Field Definitions ............156
19.7 Compatibility with Previous Versions ..............160
19.7.1 Compatibility with HTTP/1.0 Persistent
Connections............................................161
 
 
 
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 6]
RFC 2068 HTTP/1.1 January 1997
 
 
1 Introduction
 
1.1 Purpose
 
The Hypertext Transfer Protocol (HTTP) is an application-level
protocol for distributed, collaborative, hypermedia information
systems. HTTP has been in use by the World-Wide Web global
information initiative since 1990. The first version of HTTP,
referred to as HTTP/0.9, was a simple protocol for raw data transfer
across the Internet. HTTP/1.0, as defined by RFC 1945 [6], improved
the protocol by allowing messages to be in the format of MIME-like
messages, containing metainformation about the data transferred and
modifiers on the request/response semantics. However, HTTP/1.0 does
not sufficiently take into consideration the effects of hierarchical
proxies, caching, the need for persistent connections, and virtual
hosts. In addition, the proliferation of incompletely-implemented
applications calling themselves "HTTP/1.0" has necessitated a
protocol version change in order for two communicating applications
to determine each other's true capabilities.
 
This specification defines the protocol referred to as "HTTP/1.1".
This protocol includes more stringent requirements than HTTP/1.0 in
order to ensure reliable implementation of its features.
 
Practical information systems require more functionality than simple
retrieval, including search, front-end update, and annotation. HTTP
allows an open-ended set of methods that indicate the purpose of a
request. It builds on the discipline of reference provided by the
Uniform Resource Identifier (URI) [3][20], as a location (URL) [4] or
name (URN) , for indicating the resource to which a method is to be
applied. Messages are passed in a format similar to that used by
Internet mail as defined by the Multipurpose Internet Mail Extensions
(MIME).
 
HTTP is also used as a generic protocol for communication between
user agents and proxies/gateways to other Internet systems, including
those supported by the SMTP [16], NNTP [13], FTP [18], Gopher [2],
and WAIS [10] protocols. In this way, HTTP allows basic hypermedia
access to resources available from diverse applications.
 
1.2 Requirements
 
This specification uses the same words as RFC 1123 [8] for defining
the significance of each particular requirement. These words are:
 
MUST
This word or the adjective "required" means that the item is an
absolute requirement of the specification.
 
 
 
Fielding, et. al. Standards Track [Page 7]
RFC 2068 HTTP/1.1 January 1997
 
 
SHOULD
This word or the adjective "recommended" means that there may
exist valid reasons in particular circumstances to ignore this
item, but the full implications should be understood and the case
carefully weighed before choosing a different course.
 
MAY
This word or the adjective "optional" means that this item is
truly optional. One vendor may choose to include the item because
a particular marketplace requires it or because it enhances the
product, for example; another vendor may omit the same item.
 
An implementation is not compliant if it fails to satisfy one or more
of the MUST requirements for the protocols it implements. An
implementation that satisfies all the MUST and all the SHOULD
requirements for its protocols is said to be "unconditionally
compliant"; one that satisfies all the MUST requirements but not all
the SHOULD requirements for its protocols is said to be
"conditionally compliant."
 
1.3 Terminology
 
This specification uses a number of terms to refer to the roles
played by participants in, and objects of, the HTTP communication.
 
connection
A transport layer virtual circuit established between two programs
for the purpose of communication.
 
message
The basic unit of HTTP communication, consisting of a structured
sequence of octets matching the syntax defined in section 4 and
transmitted via the connection.
 
request
An HTTP request message, as defined in section 5.
 
response
An HTTP response message, as defined in section 6.
 
resource
A network data object or service that can be identified by a URI,
as defined in section 3.2. Resources may be available in multiple
representations (e.g. multiple languages, data formats, size,
resolutions) or vary in other ways.
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 8]
RFC 2068 HTTP/1.1 January 1997
 
 
entity
The information transferred as the payload of a request or
response. An entity consists of metainformation in the form of
entity-header fields and content in the form of an entity-body, as
described in section 7.
 
representation
An entity included with a response that is subject to content
negotiation, as described in section 12. There may exist multiple
representations associated with a particular response status.
 
content negotiation
The mechanism for selecting the appropriate representation when
servicing a request, as described in section 12. The
representation of entities in any response can be negotiated
(including error responses).
 
variant
A resource may have one, or more than one, representation(s)
associated with it at any given instant. Each of these
representations is termed a `variant.' Use of the term `variant'
does not necessarily imply that the resource is subject to content
negotiation.
 
client
A program that establishes connections for the purpose of sending
requests.
 
user agent
The client which initiates a request. These are often browsers,
editors, spiders (web-traversing robots), or other end user tools.
 
server
An application program that accepts connections in order to
service requests by sending back responses. Any given program may
be capable of being both a client and a server; our use of these
terms refers only to the role being performed by the program for a
particular connection, rather than to the program's capabilities
in general. Likewise, any server may act as an origin server,
proxy, gateway, or tunnel, switching behavior based on the nature
of each request.
 
origin server
The server on which a given resource resides or is to be created.
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 9]
RFC 2068 HTTP/1.1 January 1997
 
 
proxy
An intermediary program which acts as both a server and a client
for the purpose of making requests on behalf of other clients.
Requests are serviced internally or by passing them on, with
possible translation, to other servers. A proxy must implement
both the client and server requirements of this specification.
 
gateway
A server which acts as an intermediary for some other server.
Unlike a proxy, a gateway receives requests as if it were the
origin server for the requested resource; the requesting client
may not be aware that it is communicating with a gateway.
 
tunnel
An intermediary program which is acting as a blind relay between
two connections. Once active, a tunnel is not considered a party
to the HTTP communication, though the tunnel may have been
initiated by an HTTP request. The tunnel ceases to exist when both
ends of the relayed connections are closed.
 
cache
A program's local store of response messages and the subsystem
that controls its message storage, retrieval, and deletion. A
cache stores cachable responses in order to reduce the response
time and network bandwidth consumption on future, equivalent
requests. Any client or server may include a cache, though a cache
cannot be used by a server that is acting as a tunnel.
 
cachable
A response is cachable if a cache is allowed to store a copy of
the response message for use in answering subsequent requests. The
rules for determining the cachability of HTTP responses are
defined in section 13. Even if a resource is cachable, there may
be additional constraints on whether a cache can use the cached
copy for a particular request.
 
first-hand
A response is first-hand if it comes directly and without
unnecessary delay from the origin server, perhaps via one or more
proxies. A response is also first-hand if its validity has just
been checked directly with the origin server.
 
explicit expiration time
The time at which the origin server intends that an entity should
no longer be returned by a cache without further validation.
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 10]
RFC 2068 HTTP/1.1 January 1997
 
 
heuristic expiration time
An expiration time assigned by a cache when no explicit expiration
time is available.
 
age
The age of a response is the time since it was sent by, or
successfully validated with, the origin server.
 
freshness lifetime
The length of time between the generation of a response and its
expiration time.
 
fresh
A response is fresh if its age has not yet exceeded its freshness
lifetime.
 
stale
A response is stale if its age has passed its freshness lifetime.
 
semantically transparent
A cache behaves in a "semantically transparent" manner, with
respect to a particular response, when its use affects neither the
requesting client nor the origin server, except to improve
performance. When a cache is semantically transparent, the client
receives exactly the same response (except for hop-by-hop headers)
that it would have received had its request been handled directly
by the origin server.
 
validator
A protocol element (e.g., an entity tag or a Last-Modified time)
that is used to find out whether a cache entry is an equivalent
copy of an entity.
 
1.4 Overall Operation
 
The HTTP protocol is a request/response protocol. A client sends a
request to the server in the form of a request method, URI, and
protocol version, followed by a MIME-like message containing request
modifiers, client information, and possible body content over a
connection with a server. The server responds with a status line,
including the message's protocol version and a success or error code,
followed by a MIME-like message containing server information, entity
metainformation, and possible entity-body content. The relationship
between HTTP and MIME is described in appendix 19.4.
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 11]
RFC 2068 HTTP/1.1 January 1997
 
 
Most HTTP communication is initiated by a user agent and consists of
a request to be applied to a resource on some origin server. In the
simplest case, this may be accomplished via a single connection (v)
between the user agent (UA) and the origin server (O).
 
request chain ------------------------>
UA -------------------v------------------- O
<----------------------- response chain
 
A more complicated situation occurs when one or more intermediaries
are present in the request/response chain. There are three common
forms of intermediary: proxy, gateway, and tunnel. A proxy is a
forwarding agent, receiving requests for a URI in its absolute form,
rewriting all or part of the message, and forwarding the reformatted
request toward the server identified by the URI. A gateway is a
receiving agent, acting as a layer above some other server(s) and, if
necessary, translating the requests to the underlying server's
protocol. A tunnel acts as a relay point between two connections
without changing the messages; tunnels are used when the
communication needs to pass through an intermediary (such as a
firewall) even when the intermediary cannot understand the contents
of the messages.
 
request chain -------------------------------------->
UA -----v----- A -----v----- B -----v----- C -----v----- O
<------------------------------------- response chain
 
The figure above shows three intermediaries (A, B, and C) between the
user agent and origin server. A request or response message that
travels the whole chain will pass through four separate connections.
This distinction is important because some HTTP communication options
may apply only to the connection with the nearest, non-tunnel
neighbor, only to the end-points of the chain, or to all connections
along the chain. Although the diagram is linear, each participant
may be engaged in multiple, simultaneous communications. For example,
B may be receiving requests from many clients other than A, and/or
forwarding requests to servers other than C, at the same time that it
is handling A's request.
 
Any party to the communication which is not acting as a tunnel may
employ an internal cache for handling requests. The effect of a cache
is that the request/response chain is shortened if one of the
participants along the chain has a cached response applicable to that
request. The following illustrates the resulting chain if B has a
cached copy of an earlier response from O (via C) for a request which
has not been cached by UA or A.
 
 
 
 
 
Fielding, et. al. Standards Track [Page 12]
RFC 2068 HTTP/1.1 January 1997
 
 
request chain ---------->
UA -----v----- A -----v----- B - - - - - - C - - - - - - O
<--------- response chain
 
Not all responses are usefully cachable, and some requests may
contain modifiers which place special requirements on cache behavior.
HTTP requirements for cache behavior and cachable responses are
defined in section 13.
 
In fact, there are a wide variety of architectures and configurations
of caches and proxies currently being experimented with or deployed
across the World Wide Web; these systems include national hierarchies
of proxy caches to save transoceanic bandwidth, systems that
broadcast or multicast cache entries, organizations that distribute
subsets of cached data via CD-ROM, and so on. HTTP systems are used
in corporate intranets over high-bandwidth links, and for access via
PDAs with low-power radio links and intermittent connectivity. The
goal of HTTP/1.1 is to support the wide diversity of configurations
already deployed while introducing protocol constructs that meet the
needs of those who build web applications that require high
reliability and, failing that, at least reliable indications of
failure.
 
HTTP communication usually takes place over TCP/IP connections. The
default port is TCP 80, but other ports can be used. This does not
preclude HTTP from being implemented on top of any other protocol on
the Internet, or on other networks. HTTP only presumes a reliable
transport; any protocol that provides such guarantees can be used;
the mapping of the HTTP/1.1 request and response structures onto the
transport data units of the protocol in question is outside the scope
of this specification.
 
In HTTP/1.0, most implementations used a new connection for each
request/response exchange. In HTTP/1.1, a connection may be used for
one or more request/response exchanges, although connections may be
closed for a variety of reasons (see section 8.1).
 
2 Notational Conventions and Generic Grammar
 
2.1 Augmented BNF
 
All of the mechanisms specified in this document are described in
both prose and an augmented Backus-Naur Form (BNF) similar to that
used by RFC 822 [9]. Implementers will need to be familiar with the
notation in order to understand this specification. The augmented BNF
includes the following constructs:
 
 
 
 
 
Fielding, et. al. Standards Track [Page 13]
RFC 2068 HTTP/1.1 January 1997
 
 
name = definition
The name of a rule is simply the name itself (without any enclosing
"<" and ">") and is separated from its definition by the equal "="
character. Whitespace is only significant in that indentation of
continuation lines is used to indicate a rule definition that spans
more than one line. Certain basic rules are in uppercase, such as
SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle brackets are used
within definitions whenever their presence will facilitate
discerning the use of rule names.
 
"literal"
Quotation marks surround literal text. Unless stated otherwise, the
text is case-insensitive.
 
rule1 | rule2
Elements separated by a bar ("|") are alternatives, e.g., "yes |
no" will accept yes or no.
 
(rule1 rule2)
Elements enclosed in parentheses are treated as a single element.
Thus, "(elem (foo | bar) elem)" allows the token sequences "elem
foo elem" and "elem bar elem".
 
*rule
The character "*" preceding an element indicates repetition. The
full form is "<n>*<m>element" indicating at least <n> and at most
<m> occurrences of element. Default values are 0 and infinity so
that "*(element)" allows any number, including zero; "1*element"
requires at least one; and "1*2element" allows one or two.
 
[rule]
Square brackets enclose optional elements; "[foo bar]" is
equivalent to "*1(foo bar)".
 
N rule
Specific repetition: "<n>(element)" is equivalent to
"<n>*<n>(element)"; that is, exactly <n> occurrences of (element).
Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three
alphabetic characters.
 
#rule
A construct "#" is defined, similar to "*", for defining lists of
elements. The full form is "<n>#<m>element " indicating at least
<n> and at most <m> elements, each separated by one or more commas
(",") and optional linear whitespace (LWS). This makes the usual
form of lists very easy; a rule such as "( *LWS element *( *LWS ","
*LWS element )) " can be shown as "1#element". Wherever this
construct is used, null elements are allowed, but do not contribute
 
 
 
Fielding, et. al. Standards Track [Page 14]
RFC 2068 HTTP/1.1 January 1997
 
 
to the count of elements present. That is, "(element), , (element)
" is permitted, but counts as only two elements. Therefore, where
at least one element is required, at least one non-null element
must be present. Default values are 0 and infinity so that
"#element" allows any number, including zero; "1#element" requires
at least one; and "1#2element" allows one or two.
 
; comment
A semi-colon, set off some distance to the right of rule text,
starts a comment that continues to the end of line. This is a
simple way of including useful notes in parallel with the
specifications.
 
implied *LWS
The grammar described by this specification is word-based. Except
where noted otherwise, linear whitespace (LWS) can be included
between any two adjacent words (token or quoted-string), and
between adjacent tokens and delimiters (tspecials), without
changing the interpretation of a field. At least one delimiter
(tspecials) must exist between any two tokens, since they would
otherwise be interpreted as a single token.
 
2.2 Basic Rules
 
The following rules are used throughout this specification to
describe basic parsing constructs. The US-ASCII coded character set
is defined by ANSI X3.4-1986 [21].
 
OCTET = <any 8-bit sequence of data>
CHAR = <any US-ASCII character (octets 0 - 127)>
UPALPHA = <any US-ASCII uppercase letter "A".."Z">
LOALPHA = <any US-ASCII lowercase letter "a".."z">
ALPHA = UPALPHA | LOALPHA
DIGIT = <any US-ASCII digit "0".."9">
CTL = <any US-ASCII control character
(octets 0 - 31) and DEL (127)>
CR = <US-ASCII CR, carriage return (13)>
LF = <US-ASCII LF, linefeed (10)>
SP = <US-ASCII SP, space (32)>
HT = <US-ASCII HT, horizontal-tab (9)>
<"> = <US-ASCII double-quote mark (34)>
 
 
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 15]
RFC 2068 HTTP/1.1 January 1997
 
 
HTTP/1.1 defines the sequence CR LF as the end-of-line marker for all
protocol elements except the entity-body (see appendix 19.3 for
tolerant applications). The end-of-line marker within an entity-body
is defined by its associated media type, as described in section 3.7.
 
CRLF = CR LF
 
HTTP/1.1 headers can be folded onto multiple lines if the
continuation line begins with a space or horizontal tab. All linear
white space, including folding, has the same semantics as SP.
 
LWS = [CRLF] 1*( SP | HT )
 
The TEXT rule is only used for descriptive field contents and values
that are not intended to be interpreted by the message parser. Words
of *TEXT may contain characters from character sets other than ISO
8859-1 [22] only when encoded according to the rules of RFC 1522
[14].
 
TEXT = <any OCTET except CTLs,
but including LWS>
 
Hexadecimal numeric characters are used in several protocol elements.
 
HEX = "A" | "B" | "C" | "D" | "E" | "F"
| "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
 
Many HTTP/1.1 header field values consist of words separated by LWS
or special characters. These special characters MUST be in a quoted
string to be used within a parameter value.
 
token = 1*<any CHAR except CTLs or tspecials>
 
tspecials = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "\" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
 
Comments can be included in some HTTP header fields by surrounding
the comment text with parentheses. Comments are only allowed in
fields containing "comment" as part of their field value definition.
In all other fields, parentheses are considered part of the field
value.
 
comment = "(" *( ctext | comment ) ")"
ctext = <any TEXT excluding "(" and ")">
 
 
 
 
 
Fielding, et. al. Standards Track [Page 16]
RFC 2068 HTTP/1.1 January 1997
 
 
A string of text is parsed as a single word if it is quoted using
double-quote marks.
 
quoted-string = ( <"> *(qdtext) <"> )
 
qdtext = <any TEXT except <">>
 
The backslash character ("\") may be used as a single-character quoting
mechanism only within quoted-string and comment constructs.
 
quoted-pair = "\" CHAR
 
3 Protocol Parameters
 
3.1 HTTP Version
 
HTTP uses a "<major>.<minor>" numbering scheme to indicate versions
of the protocol. The protocol versioning policy is intended to allow
the sender to indicate the format of a message and its capacity for
understanding further HTTP communication, rather than the features
obtained via that communication. No change is made to the version
number for the addition of message components which do not affect
communication behavior or which only add to extensible field values.
The <minor> number is incremented when the changes made to the
protocol add features which do not change the general message parsing
algorithm, but which may add to the message semantics and imply
additional capabilities of the sender. The <major> number is
incremented when the format of a message within the protocol is
changed.
 
The version of an HTTP message is indicated by an HTTP-Version field
in the first line of the message.
 
HTTP-Version = "HTTP" "/" 1*DIGIT "." 1*DIGIT
 
Note that the major and minor numbers MUST be treated as separate
integers and that each may be incremented higher than a single digit.
Thus, HTTP/2.4 is a lower version than HTTP/2.13, which in turn is
lower than HTTP/12.3. Leading zeros MUST be ignored by recipients and
MUST NOT be sent.
 
Applications sending Request or Response messages, as defined by this
specification, MUST include an HTTP-Version of "HTTP/1.1". Use of
this version number indicates that the sending application is at
least conditionally compliant with this specification.
 
The HTTP version of an application is the highest HTTP version for
which the application is at least conditionally compliant.
 
 
 
Fielding, et. al. Standards Track [Page 17]
RFC 2068 HTTP/1.1 January 1997
 
 
Proxy and gateway applications must be careful when forwarding
messages in protocol versions different from that of the application.
Since the protocol version indicates the protocol capability of the
sender, a proxy/gateway MUST never send a message with a version
indicator which is greater than its actual version; if a higher
version request is received, the proxy/gateway MUST either downgrade
the request version, respond with an error, or switch to tunnel
behavior. Requests with a version lower than that of the
proxy/gateway's version MAY be upgraded before being forwarded; the
proxy/gateway's response to that request MUST be in the same major
version as the request.
 
Note: Converting between versions of HTTP may involve modification
of header fields required or forbidden by the versions involved.
 
3.2 Uniform Resource Identifiers
 
URIs have been known by many names: WWW addresses, Universal Document
Identifiers, Universal Resource Identifiers , and finally the
combination of Uniform Resource Locators (URL) and Names (URN). As
far as HTTP is concerned, Uniform Resource Identifiers are simply
formatted strings which identify--via name, location, or any other
characteristic--a resource.
 
3.2.1 General Syntax
 
URIs in HTTP can be represented in absolute form or relative to some
known base URI, depending upon the context of their use. The two
forms are differentiated by the fact that absolute URIs always begin
with a scheme name followed by a colon.
 
URI = ( absoluteURI | relativeURI ) [ "#" fragment ]
 
absoluteURI = scheme ":" *( uchar | reserved )
 
relativeURI = net_path | abs_path | rel_path
 
net_path = "//" net_loc [ abs_path ]
abs_path = "/" rel_path
rel_path = [ path ] [ ";" params ] [ "?" query ]
 
path = fsegment *( "/" segment )
fsegment = 1*pchar
segment = *pchar
 
params = param *( ";" param )
param = *( pchar | "/" )
 
 
 
 
Fielding, et. al. Standards Track [Page 18]
RFC 2068 HTTP/1.1 January 1997
 
 
scheme = 1*( ALPHA | DIGIT | "+" | "-" | "." )
net_loc = *( pchar | ";" | "?" )
 
query = *( uchar | reserved )
fragment = *( uchar | reserved )
 
pchar = uchar | ":" | "@" | "&" | "=" | "+"
uchar = unreserved | escape
unreserved = ALPHA | DIGIT | safe | extra | national
 
escape = "%" HEX HEX
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
extra = "!" | "*" | "'" | "(" | ")" | ","
safe = "$" | "-" | "_" | "."
unsafe = CTL | SP | <"> | "#" | "%" | "<" | ">"
national = <any OCTET excluding ALPHA, DIGIT,
reserved, extra, safe, and unsafe>
 
For definitive information on URL syntax and semantics, see RFC 1738
[4] and RFC 1808 [11]. The BNF above includes national characters not
allowed in valid URLs as specified by RFC 1738, since HTTP servers
are not restricted in the set of unreserved characters allowed to
represent the rel_path part of addresses, and HTTP proxies may
receive requests for URIs not defined by RFC 1738.
 
The HTTP protocol does not place any a priori limit on the length of
a URI. Servers MUST be able to handle the URI of any resource they
serve, and SHOULD be able to handle URIs of unbounded length if they
provide GET-based forms that could generate such URIs. A server
SHOULD return 414 (Request-URI Too Long) status if a URI is longer
than the server can handle (see section 10.4.15).
 
Note: Servers should be cautious about depending on URI lengths
above 255 bytes, because some older client or proxy implementations
may not properly support these lengths.
 
3.2.2 http URL
 
The "http" scheme is used to locate network resources via the HTTP
protocol. This section defines the scheme-specific syntax and
semantics for http URLs.
 
 
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 19]
RFC 2068 HTTP/1.1 January 1997
 
 
http_URL = "http:" "//" host [ ":" port ] [ abs_path ]
 
host = <A legal Internet host domain name
or IP address (in dotted-decimal form),
as defined by Section 2.1 of RFC 1123>
 
port = *DIGIT
 
If the port is empty or not given, port 80 is assumed. The semantics
are that the identified resource is located at the server listening
for TCP connections on that port of that host, and the Request-URI
for the resource is abs_path. The use of IP addresses in URL's SHOULD
be avoided whenever possible (see RFC 1900 [24]). If the abs_path is
not present in the URL, it MUST be given as "/" when used as a
Request-URI for a resource (section 5.1.2).
 
3.2.3 URI Comparison
 
When comparing two URIs to decide if they match or not, a client
SHOULD use a case-sensitive octet-by-octet comparison of the entire
URIs, with these exceptions:
 
o A port that is empty or not given is equivalent to the default
port for that URI;
 
o Comparisons of host names MUST be case-insensitive;
 
o Comparisons of scheme names MUST be case-insensitive;
 
o An empty abs_path is equivalent to an abs_path of "/".
 
Characters other than those in the "reserved" and "unsafe" sets (see
section 3.2) are equivalent to their ""%" HEX HEX" encodings.
 
For example, the following three URIs are equivalent:
 
http://abc.com:80/~smith/home.html
http://ABC.com/%7Esmith/home.html
http://ABC.com:/%7esmith/home.html
 
 
 
 
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 20]
RFC 2068 HTTP/1.1 January 1997
 
 
3.3 Date/Time Formats
 
3.3.1 Full Date
 
HTTP applications have historically allowed three different formats
for the representation of date/time stamps:
 
Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
 
The first format is preferred as an Internet standard and represents
a fixed-length subset of that defined by RFC 1123 (an update to RFC
822). The second format is in common use, but is based on the
obsolete RFC 850 [12] date format and lacks a four-digit year.
HTTP/1.1 clients and servers that parse the date value MUST accept
all three formats (for compatibility with HTTP/1.0), though they MUST
only generate the RFC 1123 format for representing HTTP-date values
in header fields.
 
Note: Recipients of date values are encouraged to be robust in
accepting date values that may have been sent by non-HTTP
applications, as is sometimes the case when retrieving or posting
messages via proxies/gateways to SMTP or NNTP.
 
All HTTP date/time stamps MUST be represented in Greenwich Mean Time
(GMT), without exception. This is indicated in the first two formats
by the inclusion of "GMT" as the three-letter abbreviation for time
zone, and MUST be assumed when reading the asctime format.
 
HTTP-date = rfc1123-date | rfc850-date | asctime-date
 
rfc1123-date = wkday "," SP date1 SP time SP "GMT"
rfc850-date = weekday "," SP date2 SP time SP "GMT"
asctime-date = wkday SP date3 SP time SP 4DIGIT
 
date1 = 2DIGIT SP month SP 4DIGIT
; day month year (e.g., 02 Jun 1982)
date2 = 2DIGIT "-" month "-" 2DIGIT
; day-month-year (e.g., 02-Jun-82)
date3 = month SP ( 2DIGIT | ( SP 1DIGIT ))
; month day (e.g., Jun 2)
 
time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
; 00:00:00 - 23:59:59
 
wkday = "Mon" | "Tue" | "Wed"
| "Thu" | "Fri" | "Sat" | "Sun"
 
 
 
Fielding, et. al. Standards Track [Page 21]
RFC 2068 HTTP/1.1 January 1997
 
 
weekday = "Monday" | "Tuesday" | "Wednesday"
| "Thursday" | "Friday" | "Saturday" | "Sunday"
 
month = "Jan" | "Feb" | "Mar" | "Apr"
| "May" | "Jun" | "Jul" | "Aug"
| "Sep" | "Oct" | "Nov" | "Dec"
 
Note: HTTP requirements for the date/time stamp format apply only
to their usage within the protocol stream. Clients and servers are
not required to use these formats for user presentation, request
logging, etc.
 
3.3.2 Delta Seconds
 
Some HTTP header fields allow a time value to be specified as an
integer number of seconds, represented in decimal, after the time
that the message was received.
 
delta-seconds = 1*DIGIT
 
3.4 Character Sets
 
HTTP uses the same definition of the term "character set" as that
described for MIME:
 
The term "character set" is used in this document to refer to a
method used with one or more tables to convert a sequence of octets
into a sequence of characters. Note that unconditional conversion
in the other direction is not required, in that not all characters
may be available in a given character set and a character set may
provide more than one sequence of octets to represent a particular
character. This definition is intended to allow various kinds of
character encodings, from simple single-table mappings such as US-
ASCII to complex table switching methods such as those that use ISO
2022's techniques. However, the definition associated with a MIME
character set name MUST fully specify the mapping to be performed
from octets to characters. In particular, use of external profiling
information to determine the exact mapping is not permitted.
 
Note: This use of the term "character set" is more commonly
referred to as a "character encoding." However, since HTTP and MIME
share the same registry, it is important that the terminology also
be shared.
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 22]
RFC 2068 HTTP/1.1 January 1997
 
 
HTTP character sets are identified by case-insensitive tokens. The
complete set of tokens is defined by the IANA Character Set registry
[19].
 
charset = token
 
Although HTTP allows an arbitrary token to be used as a charset
value, any token that has a predefined value within the IANA
Character Set registry MUST represent the character set defined by
that registry. Applications SHOULD limit their use of character sets
to those defined by the IANA registry.
 
3.5 Content Codings
 
Content coding values indicate an encoding transformation that has
been or can be applied to an entity. Content codings are primarily
used to allow a document to be compressed or otherwise usefully
transformed without losing the identity of its underlying media type
and without loss of information. Frequently, the entity is stored in
coded form, transmitted directly, and only decoded by the recipient.
 
content-coding = token
 
All content-coding values are case-insensitive. HTTP/1.1 uses
content-coding values in the Accept-Encoding (section 14.3) and
Content-Encoding (section 14.12) header fields. Although the value
describes the content-coding, what is more important is that it
indicates what decoding mechanism will be required to remove the
encoding.
 
The Internet Assigned Numbers Authority (IANA) acts as a registry for
content-coding value tokens. Initially, the registry contains the
following tokens:
 
gzip An encoding format produced by the file compression program "gzip"
(GNU zip) as described in RFC 1952 [25]. This format is a Lempel-
Ziv coding (LZ77) with a 32 bit CRC.
 
compress
The encoding format produced by the common UNIX file compression
program "compress". This format is an adaptive Lempel-Ziv-Welch
coding (LZW).
 
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 23]
RFC 2068 HTTP/1.1 January 1997
 
 
Note: Use of program names for the identification of encoding
formats is not desirable and should be discouraged for future
encodings. Their use here is representative of historical practice,
not good design. For compatibility with previous implementations of
HTTP, applications should consider "x-gzip" and "x-compress" to be
equivalent to "gzip" and "compress" respectively.
 
deflate The "zlib" format defined in RFC 1950[31] in combination with
the "deflate" compression mechanism described in RFC 1951[29].
 
New content-coding value tokens should be registered; to allow
interoperability between clients and servers, specifications of the
content coding algorithms needed to implement a new value should be
publicly available and adequate for independent implementation, and
conform to the purpose of content coding defined in this section.
 
3.6 Transfer Codings
 
Transfer coding values are used to indicate an encoding
transformation that has been, can be, or may need to be applied to an
entity-body in order to ensure "safe transport" through the network.
This differs from a content coding in that the transfer coding is a
property of the message, not of the original entity.
 
transfer-coding = "chunked" | transfer-extension
 
transfer-extension = token
 
All transfer-coding values are case-insensitive. HTTP/1.1 uses
transfer coding values in the Transfer-Encoding header field (section
14.40).
 
Transfer codings are analogous to the Content-Transfer-Encoding
values of MIME , which were designed to enable safe transport of
binary data over a 7-bit transport service. However, safe transport
has a different focus for an 8bit-clean transfer protocol. In HTTP,
the only unsafe characteristic of message-bodies is the difficulty in
determining the exact body length (section 7.2.2), or the desire to
encrypt data over a shared transport.
 
The chunked encoding modifies the body of a message in order to
transfer it as a series of chunks, each with its own size indicator,
followed by an optional footer containing entity-header fields. This
allows dynamically-produced content to be transferred along with the
information necessary for the recipient to verify that it has
received the full message.
 
 
 
 
 
Fielding, et. al. Standards Track [Page 24]
RFC 2068 HTTP/1.1 January 1997
 
 
Chunked-Body = *chunk
"0" CRLF
footer
CRLF
 
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
 
hex-no-zero = <HEX excluding "0">
 
chunk-size = hex-no-zero *HEX
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
 
footer = *entity-header
 
The chunked encoding is ended by a zero-sized chunk followed by the
footer, which is terminated by an empty line. The purpose of the
footer is to provide an efficient way to supply information about an
entity that is generated dynamically; applications MUST NOT send
header fields in the footer which are not explicitly defined as being
appropriate for the footer, such as Content-MD5 or future extensions
to HTTP for digital signatures or other facilities.
 
An example process for decoding a Chunked-Body is presented in
appendix 19.4.6.
 
All HTTP/1.1 applications MUST be able to receive and decode the
"chunked" transfer coding, and MUST ignore transfer coding extensions
they do not understand. A server which receives an entity-body with a
transfer-coding it does not understand SHOULD return 501
(Unimplemented), and close the connection. A server MUST NOT send
transfer-codings to an HTTP/1.0 client.
 
3.7 Media Types
 
HTTP uses Internet Media Types in the Content-Type (section 14.18)
and Accept (section 14.1) header fields in order to provide open and
extensible data typing and type negotiation.
 
media-type = type "/" subtype *( ";" parameter )
type = token
subtype = token
 
Parameters may follow the type/subtype in the form of attribute/value
pairs.
 
 
 
Fielding, et. al. Standards Track [Page 25]
RFC 2068 HTTP/1.1 January 1997
 
 
parameter = attribute "=" value
attribute = token
value = token | quoted-string
 
The type, subtype, and parameter attribute names are case-
insensitive. Parameter values may or may not be case-sensitive,
depending on the semantics of the parameter name. Linear white space
(LWS) MUST NOT be used between the type and subtype, nor between an
attribute and its value. User agents that recognize the media-type
MUST process (or arrange to be processed by any external applications
used to process that type/subtype by the user agent) the parameters
for that MIME type as described by that type/subtype definition to
the and inform the user of any problems discovered.
 
Note: some older HTTP applications do not recognize media type
parameters. When sending data to older HTTP applications,
implementations should only use media type parameters when they are
required by that type/subtype definition.
 
Media-type values are registered with the Internet Assigned Number
Authority (IANA). The media type registration process is outlined in
RFC 2048 [17]. Use of non-registered media types is discouraged.
 
3.7.1 Canonicalization and Text Defaults
 
Internet media types are registered with a canonical form. In
general, an entity-body transferred via HTTP messages MUST be
represented in the appropriate canonical form prior to its
transmission; the exception is "text" types, as defined in the next
paragraph.
 
When in canonical form, media subtypes of the "text" type use CRLF as
the text line break. HTTP relaxes this requirement and allows the
transport of text media with plain CR or LF alone representing a line
break when it is done consistently for an entire entity-body. HTTP
applications MUST accept CRLF, bare CR, and bare LF as being
representative of a line break in text media received via HTTP. In
addition, if the text is represented in a character set that does not
use octets 13 and 10 for CR and LF respectively, as is the case for
some multi-byte character sets, HTTP allows the use of whatever octet
sequences are defined by that character set to represent the
equivalent of CR and LF for line breaks. This flexibility regarding
line breaks applies only to text media in the entity-body; a bare CR
or LF MUST NOT be substituted for CRLF within any of the HTTP control
structures (such as header fields and multipart boundaries).
 
If an entity-body is encoded with a Content-Encoding, the underlying
data MUST be in a form defined above prior to being encoded.
 
 
 
Fielding, et. al. Standards Track [Page 26]
RFC 2068 HTTP/1.1 January 1997
 
 
The "charset" parameter is used with some media types to define the
character set (section 3.4) of the data. When no explicit charset
parameter is provided by the sender, media subtypes of the "text"
type are defined to have a default charset value of "ISO-8859-1" when
received via HTTP. Data in character sets other than "ISO-8859-1" or
its subsets MUST be labeled with an appropriate charset value.
 
Some HTTP/1.0 software has interpreted a Content-Type header without
charset parameter incorrectly to mean "recipient should guess."
Senders wishing to defeat this behavior MAY include a charset
parameter even when the charset is ISO-8859-1 and SHOULD do so when
it is known that it will not confuse the recipient.
 
Unfortunately, some older HTTP/1.0 clients did not deal properly with
an explicit charset parameter. HTTP/1.1 recipients MUST respect the
charset label provided by the sender; and those user agents that have
a provision to "guess" a charset MUST use the charset from the
content-type field if they support that charset, rather than the
recipient's preference, when initially displaying a document.
 
3.7.2 Multipart Types
 
MIME provides for a number of "multipart" types -- encapsulations of
one or more entities within a single message-body. All multipart
types share a common syntax, as defined in MIME [7], and MUST
include a boundary parameter as part of the media type value. The
message body is itself a protocol element and MUST therefore use only
CRLF to represent line breaks between body-parts. Unlike in MIME, the
epilogue of any multipart message MUST be empty; HTTP applications
MUST NOT transmit the epilogue (even if the original multipart
contains an epilogue).
 
In HTTP, multipart body-parts MAY contain header fields which are
significant to the meaning of that part. A Content-Location header
field (section 14.15) SHOULD be included in the body-part of each
enclosed entity that can be identified by a URL.
 
In general, an HTTP user agent SHOULD follow the same or similar
behavior as a MIME user agent would upon receipt of a multipart type.
If an application receives an unrecognized multipart subtype, the
application MUST treat it as being equivalent to "multipart/mixed".
 
Note: The "multipart/form-data" type has been specifically defined
for carrying form data suitable for processing via the POST request
method, as described in RFC 1867 [15].
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 27]
RFC 2068 HTTP/1.1 January 1997
 
 
3.8 Product Tokens
 
Product tokens are used to allow communicating applications to
identify themselves by software name and version. Most fields using
product tokens also allow sub-products which form a significant part
of the application to be listed, separated by whitespace. By
convention, the products are listed in order of their significance
for identifying the application.
 
product = token ["/" product-version]
product-version = token
 
Examples:
 
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
Server: Apache/0.8.4
 
Product tokens should be short and to the point -- use of them for
advertising or other non-essential information is explicitly
forbidden. Although any token character may appear in a product-
version, this token SHOULD only be used for a version identifier
(i.e., successive versions of the same product SHOULD only differ in
the product-version portion of the product value).
 
3.9 Quality Values
 
HTTP content negotiation (section 12) uses short "floating point"
numbers to indicate the relative importance ("weight") of various
negotiable parameters. A weight is normalized to a real number in the
range 0 through 1, where 0 is the minimum and 1 the maximum value.
HTTP/1.1 applications MUST NOT generate more than three digits after
the decimal point. User configuration of these values SHOULD also be
limited in this fashion.
 
qvalue = ( "0" [ "." 0*3DIGIT ] )
| ( "1" [ "." 0*3("0") ] )
 
"Quality values" is a misnomer, since these values merely represent
relative degradation in desired quality.
 
3.10 Language Tags
 
A language tag identifies a natural language spoken, written, or
otherwise conveyed by human beings for communication of information
to other human beings. Computer languages are explicitly excluded.
HTTP uses language tags within the Accept-Language and Content-
Language fields.
 
 
 
 
Fielding, et. al. Standards Track [Page 28]
RFC 2068 HTTP/1.1 January 1997
 
 
The syntax and registry of HTTP language tags is the same as that
defined by RFC 1766 [1]. In summary, a language tag is composed of 1
or more parts: A primary language tag and a possibly empty series of
subtags:
 
language-tag = primary-tag *( "-" subtag )
 
primary-tag = 1*8ALPHA
subtag = 1*8ALPHA
 
Whitespace is not allowed within the tag and all tags are case-
insensitive. The name space of language tags is administered by the
IANA. Example tags include:
 
en, en-US, en-cockney, i-cherokee, x-pig-latin
 
where any two-letter primary-tag is an ISO 639 language abbreviation
and any two-letter initial subtag is an ISO 3166 country code. (The
last three tags above are not registered tags; all but the last are
examples of tags which could be registered in future.)
 
3.11 Entity Tags
 
Entity tags are used for comparing two or more entities from the same
requested resource. HTTP/1.1 uses entity tags in the ETag (section
14.20), If-Match (section 14.25), If-None-Match (section 14.26), and
If-Range (section 14.27) header fields. The definition of how they
are used and compared as cache validators is in section 13.3.3. An
entity tag consists of an opaque quoted string, possibly prefixed by
a weakness indicator.
 
entity-tag = [ weak ] opaque-tag
 
weak = "W/"
opaque-tag = quoted-string
 
A "strong entity tag" may be shared by two entities of a resource
only if they are equivalent by octet equality.
 
A "weak entity tag," indicated by the "W/" prefix, may be shared by
two entities of a resource only if the entities are equivalent and
could be substituted for each other with no significant change in
semantics. A weak entity tag can only be used for weak comparison.
 
An entity tag MUST be unique across all versions of all entities
associated with a particular resource. A given entity tag value may
be used for entities obtained by requests on different URIs without
implying anything about the equivalence of those entities.
 
 
 
Fielding, et. al. Standards Track [Page 29]
RFC 2068 HTTP/1.1 January 1997
 
 
3.12 Range Units
 
HTTP/1.1 allows a client to request that only part (a range of) the
response entity be included within the response. HTTP/1.1 uses range
units in the Range (section 14.36) and Content-Range (section 14.17)
header fields. An entity may be broken down into subranges according
to various structural units.
 
range-unit = bytes-unit | other-range-unit
 
bytes-unit = "bytes"
other-range-unit = token
 
The only range unit defined by HTTP/1.1 is "bytes". HTTP/1.1
implementations may ignore ranges specified using other units.
HTTP/1.1 has been designed to allow implementations of applications
that do not depend on knowledge of ranges.
 
4 HTTP Message
 
4.1 Message Types
 
HTTP messages consist of requests from client to server and responses
from server to client.
 
HTTP-message = Request | Response ; HTTP/1.1 messages
 
Request (section 5) and Response (section 6) messages use the generic
message format of RFC 822 [9] for transferring entities (the payload
of the message). Both types of message consist of a start-line, one
or more header fields (also known as "headers"), an empty line (i.e.,
a line with nothing preceding the CRLF) indicating the end of the
header fields, and an optional message-body.
 
generic-message = start-line
*message-header
CRLF
[ message-body ]
 
start-line = Request-Line | Status-Line
 
In the interest of robustness, servers SHOULD ignore any empty
line(s) received where a Request-Line is expected. In other words, if
the server is reading the protocol stream at the beginning of a
message and receives a CRLF first, it should ignore the CRLF.
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 30]
RFC 2068 HTTP/1.1 January 1997
 
 
Note: certain buggy HTTP/1.0 client implementations generate an
extra CRLF's after a POST request. To restate what is explicitly
forbidden by the BNF, an HTTP/1.1 client must not preface or follow
a request with an extra CRLF.
 
4.2 Message Headers
 
HTTP header fields, which include general-header (section 4.5),
request-header (section 5.3), response-header (section 6.2), and
entity-header (section 7.1) fields, follow the same generic format as
that given in Section 3.1 of RFC 822 [9]. Each header field consists
of a name followed by a colon (":") and the field value. Field names
are case-insensitive. The field value may be preceded by any amount
of LWS, though a single SP is preferred. Header fields can be
extended over multiple lines by preceding each extra line with at
least one SP or HT. Applications SHOULD follow "common form" when
generating HTTP constructs, since there might exist some
implementations that fail to accept anything beyond the common forms.
 
message-header = field-name ":" [ field-value ] CRLF
 
field-name = token
field-value = *( field-content | LWS )
 
field-content = <the OCTETs making up the field-value
and consisting of either *TEXT or combinations
of token, tspecials, and quoted-string>
 
The order in which header fields with differing field names are
received is not significant. However, it is "good practice" to send
general-header fields first, followed by request-header or response-
header fields, and ending with the entity-header fields.
 
Multiple message-header fields with the same field-name may be
present in a message if and only if the entire field-value for that
header field is defined as a comma-separated list [i.e., #(values)].
It MUST be possible to combine the multiple header fields into one
"field-name: field-value" pair, without changing the semantics of the
message, by appending each subsequent field-value to the first, each
separated by a comma. The order in which header fields with the same
field-name are received is therefore significant to the
interpretation of the combined field value, and thus a proxy MUST NOT
change the order of these field values when a message is forwarded.
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 31]
RFC 2068 HTTP/1.1 January 1997
 
 
4.3 Message Body
 
The message-body (if any) of an HTTP message is used to carry the
entity-body associated with the request or response. The message-body
differs from the entity-body only when a transfer coding has been
applied, as indicated by the Transfer-Encoding header field (section
14.40).
 
message-body = entity-body
| <entity-body encoded as per Transfer-Encoding>
 
Transfer-Encoding MUST be used to indicate any transfer codings
applied by an application to ensure safe and proper transfer of the
message. Transfer-Encoding is a property of the message, not of the
entity, and thus can be added or removed by any application along the
request/response chain.
 
The rules for when a message-body is allowed in a message differ for
requests and responses.
 
The presence of a message-body in a request is signaled by the
inclusion of a Content-Length or Transfer-Encoding header field in
the request's message-headers. A message-body MAY be included in a
request only when the request method (section 5.1.1) allows an
entity-body.
 
For response messages, whether or not a message-body is included with
a message is dependent on both the request method and the response
status code (section 6.1.1). All responses to the HEAD request method
MUST NOT include a message-body, even though the presence of entity-
header fields might lead one to believe they do. All 1xx
(informational), 204 (no content), and 304 (not modified) responses
MUST NOT include a message-body. All other responses do include a
message-body, although it may be of zero length.
 
4.4 Message Length
 
When a message-body is included with a message, the length of that
body is determined by one of the following (in order of precedence):
 
1. Any response message which MUST NOT include a message-body
(such as the 1xx, 204, and 304 responses and any response to a HEAD
request) is always terminated by the first empty line after the
header fields, regardless of the entity-header fields present in the
message.
 
2. If a Transfer-Encoding header field (section 14.40) is present and
indicates that the "chunked" transfer coding has been applied, then
 
 
 
Fielding, et. al. Standards Track [Page 32]
RFC 2068 HTTP/1.1 January 1997
 
 
the length is defined by the chunked encoding (section 3.6).
 
3. If a Content-Length header field (section 14.14) is present, its
value in bytes represents the length of the message-body.
 
4. If the message uses the media type "multipart/byteranges", which is
self-delimiting, then that defines the length. This media type MUST
NOT be used unless the sender knows that the recipient can parse it;
the presence in a request of a Range header with multiple byte-range
specifiers implies that the client can parse multipart/byteranges
responses.
 
5. By the server closing the connection. (Closing the connection
cannot be used to indicate the end of a request body, since that
would leave no possibility for the server to send back a response.)
 
For compatibility with HTTP/1.0 applications, HTTP/1.1 requests
containing a message-body MUST include a valid Content-Length header
field unless the server is known to be HTTP/1.1 compliant. If a
request contains a message-body and a Content-Length is not given,
the server SHOULD respond with 400 (bad request) if it cannot
determine the length of the message, or with 411 (length required) if
it wishes to insist on receiving a valid Content-Length.
 
All HTTP/1.1 applications that receive entities MUST accept the
"chunked" transfer coding (section 3.6), thus allowing this mechanism
to be used for messages when the message length cannot be determined
in advance.
 
Messages MUST NOT include both a Content-Length header field and the
"chunked" transfer coding. If both are received, the Content-Length
MUST be ignored.
 
When a Content-Length is given in a message where a message-body is
allowed, its field value MUST exactly match the number of OCTETs in
the message-body. HTTP/1.1 user agents MUST notify the user when an
invalid length is received and detected.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 33]
RFC 2068 HTTP/1.1 January 1997
 
 
4.5 General Header Fields
 
There are a few header fields which have general applicability for
both request and response messages, but which do not apply to the
entity being transferred. These header fields apply only to the
message being transmitted.
 
general-header = Cache-Control ; Section 14.9
| Connection ; Section 14.10
| Date ; Section 14.19
| Pragma ; Section 14.32
| Transfer-Encoding ; Section 14.40
| Upgrade ; Section 14.41
| Via ; Section 14.44
 
General-header field names can be extended reliably only in
combination with a change in the protocol version. However, new or
experimental header fields may be given the semantics of general
header fields if all parties in the communication recognize them to
be general-header fields. Unrecognized header fields are treated as
entity-header fields.
 
5 Request
 
A request message from a client to a server includes, within the
first line of that message, the method to be applied to the resource,
the identifier of the resource, and the protocol version in use.
 
Request = Request-Line ; Section 5.1
*( general-header ; Section 4.5
| request-header ; Section 5.3
| entity-header ) ; Section 7.1
CRLF
[ message-body ] ; Section 7.2
 
5.1 Request-Line
 
The Request-Line begins with a method token, followed by the
Request-URI and the protocol version, and ending with CRLF. The
elements are separated by SP characters. No CR or LF are allowed
except in the final CRLF sequence.
 
Request-Line = Method SP Request-URI SP HTTP-Version CRLF
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 34]
RFC 2068 HTTP/1.1 January 1997
 
 
5.1.1 Method
 
The Method token indicates the method to be performed on the resource
identified by the Request-URI. The method is case-sensitive.
 
Method = "OPTIONS" ; Section 9.2
| "GET" ; Section 9.3
| "HEAD" ; Section 9.4
| "POST" ; Section 9.5
| "PUT" ; Section 9.6
| "DELETE" ; Section 9.7
| "TRACE" ; Section 9.8
| extension-method
 
extension-method = token
 
The list of methods allowed by a resource can be specified in an
Allow header field (section 14.7). The return code of the response
always notifies the client whether a method is currently allowed on a
resource, since the set of allowed methods can change dynamically.
Servers SHOULD return the status code 405 (Method Not Allowed) if the
method is known by the server but not allowed for the requested
resource, and 501 (Not Implemented) if the method is unrecognized or
not implemented by the server. The list of methods known by a server
can be listed in a Public response-header field (section 14.35).
 
The methods GET and HEAD MUST be supported by all general-purpose
servers. All other methods are optional; however, if the above
methods are implemented, they MUST be implemented with the same
semantics as those specified in section 9.
 
5.1.2 Request-URI
 
The Request-URI is a Uniform Resource Identifier (section 3.2) and
identifies the resource upon which to apply the request.
 
Request-URI = "*" | absoluteURI | abs_path
 
The three options for Request-URI are dependent on the nature of the
request. The asterisk "*" means that the request does not apply to a
particular resource, but to the server itself, and is only allowed
when the method used does not necessarily apply to a resource. One
example would be
 
OPTIONS * HTTP/1.1
 
The absoluteURI form is required when the request is being made to a
proxy. The proxy is requested to forward the request or service it
 
 
 
Fielding, et. al. Standards Track [Page 35]
RFC 2068 HTTP/1.1 January 1997
 
 
from a valid cache, and return the response. Note that the proxy MAY
forward the request on to another proxy or directly to the server
specified by the absoluteURI. In order to avoid request loops, a
proxy MUST be able to recognize all of its server names, including
any aliases, local variations, and the numeric IP address. An example
Request-Line would be:
 
GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1
 
To allow for transition to absoluteURIs in all requests in future
versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI
form in requests, even though HTTP/1.1 clients will only generate
them in requests to proxies.
 
The most common form of Request-URI is that used to identify a
resource on an origin server or gateway. In this case the absolute
path of the URI MUST be transmitted (see section 3.2.1, abs_path) as
the Request-URI, and the network location of the URI (net_loc) MUST
be transmitted in a Host header field. For example, a client wishing
to retrieve the resource above directly from the origin server would
create a TCP connection to port 80 of the host "www.w3.org" and send
the lines:
 
GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org
 
followed by the remainder of the Request. Note that the absolute path
cannot be empty; if none is present in the original URI, it MUST be
given as "/" (the server root).
 
If a proxy receives a request without any path in the Request-URI and
the method specified is capable of supporting the asterisk form of
request, then the last proxy on the request chain MUST forward the
request with "*" as the final Request-URI. For example, the request
 
OPTIONS http://www.ics.uci.edu:8001 HTTP/1.1
 
would be forwarded by the proxy as
 
OPTIONS * HTTP/1.1
Host: www.ics.uci.edu:8001
 
after connecting to port 8001 of host "www.ics.uci.edu".
 
The Request-URI is transmitted in the format specified in section
3.2.1. The origin server MUST decode the Request-URI in order to
properly interpret the request. Servers SHOULD respond to invalid
Request-URIs with an appropriate status code.
 
 
 
Fielding, et. al. Standards Track [Page 36]
RFC 2068 HTTP/1.1 January 1997
 
 
In requests that they forward, proxies MUST NOT rewrite the
"abs_path" part of a Request-URI in any way except as noted above to
replace a null abs_path with "*", no matter what the proxy does in
its internal implementation.
 
Note: The "no rewrite" rule prevents the proxy from changing the
meaning of the request when the origin server is improperly using a
non-reserved URL character for a reserved purpose. Implementers
should be aware that some pre-HTTP/1.1 proxies have been known to
rewrite the Request-URI.
 
5.2 The Resource Identified by a Request
 
HTTP/1.1 origin servers SHOULD be aware that the exact resource
identified by an Internet request is determined by examining both the
Request-URI and the Host header field.
 
An origin server that does not allow resources to differ by the
requested host MAY ignore the Host header field value. (But see
section 19.5.1 for other requirements on Host support in HTTP/1.1.)
 
An origin server that does differentiate resources based on the host
requested (sometimes referred to as virtual hosts or vanity
hostnames) MUST use the following rules for determining the requested
resource on an HTTP/1.1 request:
 
1. If Request-URI is an absoluteURI, the host is part of the
Request-URI. Any Host header field value in the request MUST be
ignored.
 
2. If the Request-URI is not an absoluteURI, and the request
includes a Host header field, the host is determined by the Host
header field value.
 
3. If the host as determined by rule 1 or 2 is not a valid host on
the server, the response MUST be a 400 (Bad Request) error
message.
 
Recipients of an HTTP/1.0 request that lacks a Host header field MAY
attempt to use heuristics (e.g., examination of the URI path for
something unique to a particular host) in order to determine what
exact resource is being requested.
 
5.3 Request Header Fields
 
The request-header fields allow the client to pass additional
information about the request, and about the client itself, to the
server. These fields act as request modifiers, with semantics
 
 
 
Fielding, et. al. Standards Track [Page 37]
RFC 2068 HTTP/1.1 January 1997
 
 
equivalent to the parameters on a programming language method
invocation.
 
request-header = Accept ; Section 14.1
| Accept-Charset ; Section 14.2
| Accept-Encoding ; Section 14.3
| Accept-Language ; Section 14.4
| Authorization ; Section 14.8
| From ; Section 14.22
| Host ; Section 14.23
| If-Modified-Since ; Section 14.24
| If-Match ; Section 14.25
| If-None-Match ; Section 14.26
| If-Range ; Section 14.27
| If-Unmodified-Since ; Section 14.28
| Max-Forwards ; Section 14.31
| Proxy-Authorization ; Section 14.34
| Range ; Section 14.36
| Referer ; Section 14.37
| User-Agent ; Section 14.42
 
Request-header field names can be extended reliably only in
combination with a change in the protocol version. However, new or
experimental header fields MAY be given the semantics of request-
header fields if all parties in the communication recognize them to
be request-header fields. Unrecognized header fields are treated as
entity-header fields.
 
6 Response
 
After receiving and interpreting a request message, a server responds
with an HTTP response message.
 
Response = Status-Line ; Section 6.1
*( general-header ; Section 4.5
| response-header ; Section 6.2
| entity-header ) ; Section 7.1
CRLF
[ message-body ] ; Section 7.2
 
6.1 Status-Line
 
The first line of a Response message is the Status-Line, consisting
of the protocol version followed by a numeric status code and its
associated textual phrase, with each element separated by SP
characters. No CR or LF is allowed except in the final CRLF
sequence.
 
 
 
 
Fielding, et. al. Standards Track [Page 38]
RFC 2068 HTTP/1.1 January 1997
 
 
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
 
6.1.1 Status Code and Reason Phrase
 
The Status-Code element is a 3-digit integer result code of the
attempt to understand and satisfy the request. These codes are fully
defined in section 10. The Reason-Phrase is intended to give a short
textual description of the Status-Code. The Status-Code is intended
for use by automata and the Reason-Phrase is intended for the human
user. The client is not required to examine or display the Reason-
Phrase.
 
The first digit of the Status-Code defines the class of response. The
last two digits do not have any categorization role. There are 5
values for the first digit:
 
o 1xx: Informational - Request received, continuing process
 
o 2xx: Success - The action was successfully received, understood,
and accepted
 
o 3xx: Redirection - Further action must be taken in order to
complete the request
 
o 4xx: Client Error - The request contains bad syntax or cannot be
fulfilled
 
o 5xx: Server Error - The server failed to fulfill an apparently
valid request
 
The individual values of the numeric status codes defined for
HTTP/1.1, and an example set of corresponding Reason-Phrase's, are
presented below. The reason phrases listed here are only recommended
-- they may be replaced by local equivalents without affecting the
protocol.
 
Status-Code = "100" ; Continue
| "101" ; Switching Protocols
| "200" ; OK
| "201" ; Created
| "202" ; Accepted
| "203" ; Non-Authoritative Information
| "204" ; No Content
| "205" ; Reset Content
| "206" ; Partial Content
| "300" ; Multiple Choices
| "301" ; Moved Permanently
| "302" ; Moved Temporarily
 
 
 
Fielding, et. al. Standards Track [Page 39]
RFC 2068 HTTP/1.1 January 1997
 
 
| "303" ; See Other
| "304" ; Not Modified
| "305" ; Use Proxy
| "400" ; Bad Request
| "401" ; Unauthorized
| "402" ; Payment Required
| "403" ; Forbidden
| "404" ; Not Found
| "405" ; Method Not Allowed
| "406" ; Not Acceptable
| "407" ; Proxy Authentication Required
| "408" ; Request Time-out
| "409" ; Conflict
| "410" ; Gone
| "411" ; Length Required
| "412" ; Precondition Failed
| "413" ; Request Entity Too Large
| "414" ; Request-URI Too Large
| "415" ; Unsupported Media Type
| "500" ; Internal Server Error
| "501" ; Not Implemented
| "502" ; Bad Gateway
| "503" ; Service Unavailable
| "504" ; Gateway Time-out
| "505" ; HTTP Version not supported
| extension-code
 
extension-code = 3DIGIT
 
Reason-Phrase = *<TEXT, excluding CR, LF>
 
HTTP status codes are extensible. HTTP applications are not required
to understand the meaning of all registered status codes, though such
understanding is obviously desirable. However, applications MUST
understand the class of any status code, as indicated by the first
digit, and treat any unrecognized response as being equivalent to the
x00 status code of that class, with the exception that an
unrecognized response MUST NOT be cached. For example, if an
unrecognized status code of 431 is received by the client, it can
safely assume that there was something wrong with its request and
treat the response as if it had received a 400 status code. In such
cases, user agents SHOULD present to the user the entity returned
with the response, since that entity is likely to include human-
readable information which will explain the unusual status.
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 40]
RFC 2068 HTTP/1.1 January 1997
 
 
6.2 Response Header Fields
 
The response-header fields allow the server to pass additional
information about the response which cannot be placed in the Status-
Line. These header fields give information about the server and about
further access to the resource identified by the Request-URI.
 
response-header = Age ; Section 14.6
| Location ; Section 14.30
| Proxy-Authenticate ; Section 14.33
| Public ; Section 14.35
| Retry-After ; Section 14.38
| Server ; Section 14.39
| Vary ; Section 14.43
| Warning ; Section 14.45
| WWW-Authenticate ; Section 14.46
 
Response-header field names can be extended reliably only in
combination with a change in the protocol version. However, new or
experimental header fields MAY be given the semantics of response-
header fields if all parties in the communication recognize them to
be response-header fields. Unrecognized header fields are treated as
entity-header fields.
 
7 Entity
 
Request and Response messages MAY transfer an entity if not otherwise
restricted by the request method or response status code. An entity
consists of entity-header fields and an entity-body, although some
responses will only include the entity-headers.
 
In this section, both sender and recipient refer to either the client
or the server, depending on who sends and who receives the entity.
 
7.1 Entity Header Fields
 
Entity-header fields define optional metainformation about the
entity-body or, if no body is present, about the resource identified
by the request.
 
 
 
 
 
 
 
 
 
 
 
 
Fielding, et. al. Standards Track [Page 41]
RFC 2068 HTTP/1.1 January 1997
 
 
entity-header = Allow ; Section 14.7
| Content-Base ; Section 14.11
| Content-Encoding ; Section 14.12
| Content-Language ; Section 14.13
| Content-Length ; Section 14.14
| Content-Location ; Section 14.15
| Content-MD5 ; Section 14.16
| Content-Range ; Section 14.17
| Content-Type ; Section 14.18
| ETag ; Section 14.20
| Expires ; Section 14.21
| Last-Modified ; Section 14.29
| extension-header
 
extension-header = message-header
 
The extension-header mechanism allows additional entity-header fields
to be defined without changing the protocol, but these fields cannot
be assumed to be recognizable by the recipient. Unrecognized header
fields SHOULD be ignored by the recipient and forwarded by proxies.
 
7.2 Entity Body
 
The entity-body (if any) sent with an HTTP request or response is in
a format and encoding defined by the entity-header fields.
 
entity-body = *OCTET
 
An entity-body is only present in a message when a message-body is
present, as described in section 4.3. The entity-body is obtained
from the message-body by decoding any Transfer-Encoding that may have
been applied to ensure safe and proper transfer of the message.
 
7.2.1 Type
 
When an entity-body is included with a message, the data type of that
body is determined via the header fields Content-Type and Content-
Encoding. These define a two-layer, ordered encoding model:
 
entity-body := Content-Encoding( Content-Type( data ) )
 
Content-Type specifies the media type of the underlying data.
Content-Encoding may be used to indicate any additional content
codings applied to the data, usually for the purpose of data
compression, that are a property of the requested resource. There is
no default encoding.
 
 
 
 
 
Fielding, et. al. Standards Track [Page 42]
RFC 2068 HTTP/1.1 January 1997
 
 
Any HTTP/1.1 message containing an entity-body SHOULD include a
Content-Type header field defining the media type of that body. If
and only if the media type is not given by a Content-Type field, the
recipient MAY attempt to guess the media type via inspection of its
content and/or the name extension(s) of the URL used to identify the
resource. If the media type remains unknown, the recipient SHOULD
treat it as type "application/octet-stream".
 
7.2.2 Length
 
The length of an entity-body is the length of the message-body after
any transfer codings have been removed. Section 4.4 defines how the
length of a message-body is determined.
 
8 Connections
 
8.1 Persistent Connections
 
8.1.1 Purpose
 
Prior to persistent connections, a separate TCP connection was
established to fetch each URL, increasing the load on HTTP servers
and causing congestion on the Internet. The use of inline images and
other associated data often requires a client to make multiple
requests of the same server in a short amount of time. Analyses of
these performance problems are available [30][27]; analysis and
results from a prototype implementation are in [26].
 
Persistent HTTP connections have a number of advantages:
 
o By opening and closing fewer TCP connections, CPU time is saved,
and memory used for TCP protocol control blocks is also saved.
o HTTP requests and responses can be pipelined on a connection.
Pipelining allows a client to make multiple requests without
waiting for each response, allowing a single TCP connection to be
used much more efficiently, with much lower elapsed time.
o Network congestion is reduced by reducing the number of packets
caused by TCP opens, and by allowing TCP sufficient time to
determine the congestion state of the network.
o HTTP can evolve more gracefully; since errors can be reported
without the penalty of closing the TCP connection. Clients using
future versions of HTTP might optimistically try a new feature, but
if communicating with an older server, retry with old semantics
after an error is reported.
 
HTTP implementations SHOULD implement persistent connections.
 
 
 
 
 
Fielding, et. al. Standards Track [Page 43