Commit 32594c24 authored by Matthias Andree's avatar Matthias Andree

Remove support for ancient systems and portability cruft.

Assume C99 compiler. Drop pre-C99 checks.

Assume and require that all Single Unix Specification v3
specified headers are present.

Remove trio library, libesmtp and KAME get????info.?.

Reshuffle #include "fetchmail.h" where needed.

Drop compatibility cruft for BeOS, Cygwin, EMX.
parent 59e0b6af
......@@ -47,12 +47,8 @@ Stenberg and also under a liberal license:
| MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
| CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
The m4/gethostbyname_r.m4 and libesmtp/* files functions are (C) by
Brian Stafford, see the respective file headers for details (LGPL v2.1
or later).
The KAME/* files are (C) Copyright (C) 1995, 1996, 1997, and 1998 WIDE
Project, see the respective file headers for details.
The m4/gethostbyname_r.m4 files functions are (C) by Brian Stafford,
see the respective file headers for details (LGPL v2.1 or later).
All other code in the distribution incorporates the copy of GPL version 2
below by reference.
......
This diff is collapsed.
......@@ -3,7 +3,6 @@
SUBDIRS= . po
AUTOMAKE_OPTIONS= 1.11 foreign no-dist-gzip dist-xz subdir-objects
AM_CPPFLAGS= -I$(srcdir)/libesmtp
ACLOCAL_AMFLAGS= -I m4 -I m4-local
AM_YFLAGS= -d
# listing socket.$(OBJEXT) here is a hack to compile socket.c pretty
......@@ -50,17 +49,6 @@ check_PROGRAMS=
TESTS= t.smoke t.validate-xhtml10 t.validate-xhtml t.x509_name_match
LOG_COMPILER= env LC_ALL=C TZ=UTC $(SHELL)
if NEED_TRIO
noinst_LIBRARIES+= libtrio.a
libtrio_a_SOURCES= trio/triostr.c trio/trio.c trio/trionan.c \
trio/trio.h trio/triop.h trio/triodef.h \
trio/trionan.h trio/triostr.h
check_PROGRAMS+= regression
regression_SOURCES= trio/regression.c
LDADD+= libtrio.a -lm
TESTS+= t.regression
endif
fetchmail_SOURCES= fetchmail.h getopt.h \
gettext.h i18n.h kerberos.h fm_md5.h mx.h netrc.h smtp.h \
socket.h tunable.h \
......@@ -94,12 +82,6 @@ endif
if RPA_ENABLE
fetchmail_SOURCES += rpa.c
endif
if NEED_GETNAMEINFO
fetchmail_SOURCES += KAME/getnameinfo.c
endif
if NEED_GETADDRINFO
fetchmail_SOURCES += libesmtp/getaddrinfo.h libesmtp/getaddrinfo.c
endif
check_PROGRAMS += rfc822 unmime netrc rfc2047e mxget rfc822valid \
x509_name_match
......@@ -154,7 +136,6 @@ distdirs = rh-config contrib beos
EXTRA_DIST= $(DISTDOCS) $(distdirs) \
fetchmail.spec fetchmail.xpm \
trio/CHANGES trio/README \
strlcpy.3 bighand.png \
m4/codeset.m4 \
m4/gettext.m4 \
......@@ -187,7 +168,7 @@ EXTRA_DIST= $(DISTDOCS) $(distdirs) \
m4/xsize.m4 \
m4-local/ac-archive-license.txt \
m4-local/ac_ma_search_package.m4 \
$(TESTS) t.rc t.regression \
$(TESTS) t.rc \
dist-tools/html2txt \
dist-tools/manServer.pl \
Doxyfile
......
......@@ -9,8 +9,8 @@ Abbreviations in parentheses are the maintainers who committed the respective
change. MA = Matthias Andree, ESR = Eric S. Raymond, RF = Rob Funk.)
# ADVANCE WARNING OF FEATURES TO BE REMOVED OR CHANGED IN FUTURE VERSIONS
(There are no plans to remove features from a 6.4.X release, but they may be
removed from a 6.5.0 or newer release.)
(There are no plans to remove features from a 6.5.X release, but they may be
removed from a 6.6.0 or newer release.)
* Future fetchmail releases may require compilers and operating systems
that adhere to standards issued 2011 or later.
(Currently, C89 and Single Unix Specification V2 should suffice.)
......@@ -63,6 +63,21 @@ removed from a 6.5.0 or newer release.)
--------------------------------------------------------------------------------
fetchmail-6.5.0 (not yet released):
## CHANGED REQUIREMENTS
* fetchmail 6.5.0 is written in C99 and requires a SUSv3 (Single Unix
Specification v3, a superset of POSIX.1-2001 aka. IEEE Std 1003.1-2001 with
XSI extension) compliant system.
In particular, older fetchmail versions had workarounds or replacement code
for several functions standardized in the Single Unix Specification v3, these
have been removed.
The trio/ library has been removed from the distribution.
The libesmtp/getaddrinfo.? library has been removed from the distribution.
The KAME/getnameinfo.c file has been removed from the distribution.
fetchmail-6.4.0 (not yet released):
# NOTE THAT FETCHMAIL IS NO LONGER PUBLISHED THROUGH IBIBLIO.
......@@ -99,6 +114,17 @@ fetchmail-6.4.0 (not yet released):
* Fetchmail prevents buffer overruns in GSSAPI authentication with user names
beyond c. 6000 characters in length. Reported by Greg Hudson.
## CHANGED REQUIREMENTS
* fetchmail 6.4.0 is written in C99 and requires a SUSv3 (Single Unix
Specification v3, a superset of POSIX.1-2001 aka. IEEE Std 1003.1-2001 with
XSI extension) compliant system. For now, a C89 compiler should also work
if the system is SUSv3 compliant.
In particular, older fetchmail versions had workaround for several functions
standardized in the Single Unix Specification v3, these have been removed.
The trio/ library has been removed from the distribution.
## CHANGES
* fetchmail 6.3.X is unsupported.
* fetchmail now configures OpenSSL support by default.
......
......@@ -35,17 +35,13 @@ tested under the BSD variants, AIX, HP-UX versions 9 and 10, SunOS, Solaris,
NEXTSTEP, OSF 3.2, IRIX, and Rhapsody once upon a time.
The current maintainer does not have access to these systems, and assumes that
the system is at least Single-Unix-Specification V2 compatible, yet fetchmaiil
should be compilable by a C89 compiler. It currently ships with a copy of the
trio library for systems that lack snprintf().
the system is at least Single-Unix-Specification V3 compatible, and that
will also require a C99 compiler.
Fetchmail should be able to be compiled with C89, C99, C11, C++98, C++03,
Fetchmail should be able to be compiled with C99, C11, C++98, C++03,
C++11, C++14 compilers, but not C++17 because the "register" keyword is
used in some parts of the code.
Future fetchmail releases will require modern language features such as
"long long" and others, so this release is the last to support C89.
Further reading
---------------
......@@ -57,6 +53,7 @@ detailed information on recent changes, NOTES for design notes, and TODO for
a list of things that still need doing. If you want to hack on this code,
a list of known bugs and to-do items can be found in the file todo.html.
Status, source code
-------------------
......
......@@ -5,24 +5,18 @@
* For license terms, see the file COPYING in this directory.
*/
#include "config.h"
#include "fetchmail.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#ifdef HAVE_NET_SOCKET_H
#include <net/socket.h>
#else
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <netdb.h>
#include "i18n.h"
#include "mx.h"
#include "fetchmail.h"
#include "getaddrinfo.h"
#define MX_RETRIES 3
......
......@@ -5,21 +5,17 @@
*/
#include "config.h"
#include "fetchmail.h"
#include "tunable.h"
#include <stdio.h>
#include <ctype.h>
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <string.h>
#include <pwd.h>
#include <errno.h>
#include "fetchmail.h"
/* Python prettyprinting functions */
......
This diff is collapsed.
......@@ -5,13 +5,12 @@
*/
#include "config.h"
#include "fetchmail.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
#include "fetchmail.h"
#include "socket.h"
#include "i18n.h"
......
......@@ -5,78 +5,40 @@
*/
#include "config.h"
#include "fetchmail.h"
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#else /* !HAVE_FCNTL_H */
#ifdef HAVE_SYS_FCNTL_H
#include <sys/fcntl.h>
#endif /* HAVE_SYS_FCNTL_H */
#endif /* !HAVE_FCNTL_H */
#include <sys/stat.h> /* get umask(2) prototyped */
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
#if defined(QNX)
#include <unix.h>
#endif
#if !defined(HAVE_SETSID) && defined(SIGTSTP)
#if defined(HAVE_TERMIOS_H)
# include <termios.h> /* for TIOCNOTTY under Linux */
#endif
#if !defined(TIOCNOTTY) && defined(HAVE_SGTTY_H)
# include <sgtty.h> /* for TIOCNOTTY under NEXTSTEP */
#endif
#endif /* !defined(HAVE_SETSID) && defined(SIGTSTP) */
/* BSD portability hack */
#if !defined(SIGCHLD) && defined(SIGCLD)
#define SIGCHLD SIGCLD
#endif
#include "fetchmail.h"
#include "tunable.h"
static RETSIGTYPE
sigchld_handler (int sig)
/* process SIGCHLD to obtain the exit code of the terminating process */
{
#if defined(HAVE_WAITPID) /* the POSIX way */
int status;
while (waitpid(-1, &status, WNOHANG) > 0)
continue; /* swallow 'em up. */
#elif defined(HAVE_WAIT3) /* the BSD way */
pid_t pid;
#if defined(HAVE_UNION_WAIT) && !defined(__FreeBSD__)
union wait status;
#else
int status;
#endif
while ((pid = wait3(&status, WNOHANG, 0)) > 0)
continue; /* swallow 'em up. */
#else /* Zooks! Nothing to do but wait(), and hope we don't block... */
int status;
wait(&status);
#endif
lastsig = SIGCHLD;
(void)sig;
}
......@@ -92,37 +54,23 @@ SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler)
*/
{
SIGHANDLERTYPE rethandler;
#ifdef HAVE_SIGACTION
struct sigaction sa_new, sa_old;
memset (&sa_new, 0, sizeof sa_new);
sigemptyset (&sa_new.sa_mask);
sa_new.sa_handler = handler;
sa_new.sa_flags = 0;
#ifdef SA_RESTART /* SunOS 4.1 portability hack */
/* system call should restart on all signals except SIGALRM */
if (sig != SIGALRM)
sa_new.sa_flags |= SA_RESTART;
#endif
#ifdef SA_NOCLDSTOP /* SunOS 4.1 portability hack */
if (sig == SIGCHLD)
sa_new.sa_flags |= SA_NOCLDSTOP;
#endif
sigaction(sig, &sa_new, &sa_old);
rethandler = sa_old.sa_handler;
#if defined(SIGPWR)
if (sig == SIGCHLD)
sigaction(SIGPWR, &sa_new, NULL);
#endif
#else /* HAVE_SIGACTION */
rethandler = signal(sig, handler);
#if defined(SIGPWR)
if (sig == SIGCHLD)
signal(SIGPWR, handler);
#endif
/* system call should restart on all signals except SIGALRM */
siginterrupt(sig, sig == SIGALRM);
#endif /* HAVE_SIGACTION */
return rethandler;
}
......@@ -170,38 +118,11 @@ daemonize (const char *logfile)
/* Make ourselves the leader of a new process group with no
controlling terminal */
#if defined(HAVE_SETSID) /* POSIX */
/* POSIX makes this soooo easy to do */
if (setsid() < 0) {
report(stderr, "setsid (%s)\n", strerror(errno));
return(PS_IOERR);
}
#elif defined(SIGTSTP) /* BSD */
/* change process group */
#ifndef __EMX__
setpgrp(0, getpid());
#endif
/* lose controlling tty */
if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
ioctl(fd, TIOCNOTTY, (char *) 0);
close(fd); /* not checking should be safe, there were no writes */
}
#else /* SVR3 and older */
/* change process group */
#ifndef __EMX__
setpgrp();
#endif
/* lose controlling tty */
set_signal_handler(SIGHUP, SIG_IGN);
if ((childpid = fork()) < 0) {
report(stderr, "fork (%s)\n", strerror(errno));
return(PS_IOERR);
}
else if (childpid > 0) {
exit(0); /* parent */
}
#endif
nottyDetach:
......@@ -238,14 +159,15 @@ nottyDetach:
if (dup(logfd) < 0 /* stdout */
|| ((logfd == 0 || logfd >= 3) && dup(logfd) < 0)) { /* stderr */
report(stderr, "dup (%s)\n", strerror(errno));
report(stderr, "dup(): %s\n", strerror(errno));
return(PS_IOERR);
}
#ifdef HAVE_GETCWD
/* move to root directory, so we don't prevent filesystem unmounts */
chdir("/");
#endif
if (chdir("/")) {
report(stderr, "chdir(\"/\"): %s\n", strerror(errno));
return PS_IOERR;
}
/* set our umask to something reasonable (we hope) */
#if defined(DEF_UMASK)
......
......@@ -6,34 +6,22 @@
*/
#include "config.h"
#include "fetchmail.h"
#include <stdio.h>
#include <setjmp.h>
#include <errno.h>
#include <string.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif /* HAVE_MEMORY_H */
#if defined(STDC_HEADERS)
#include <stdlib.h>
#include <limits.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#if defined(HAVE_SYS_ITIMER_H)
#include <sys/itimer.h>
#endif
#include <signal.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NET_SOCKET_H
#include <net/socket.h>
#endif
#include <netdb.h>
#ifdef HAVE_PKG_hesiod
#ifdef __cplusplus
......@@ -55,8 +43,6 @@ extern "C" {
#include "i18n.h"
#include "socket.h"
#include "fetchmail.h"
#include "getaddrinfo.h"
#include "tunable.h"
#include "sdump.h"
......@@ -98,7 +84,6 @@ void resetidletimeout(void)
void set_timeout(int timeleft)
/* reset the nonresponse-timeout */
{
#if !defined(__EMX__) && !defined(__BEOS__)
struct itimerval ntimeout;
if (timeleft == 0)
......@@ -108,7 +93,6 @@ void set_timeout(int timeleft)
ntimeout.it_value.tv_sec = timeleft;
ntimeout.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &ntimeout, (struct itimerval *)NULL);
#endif
}
static RETSIGTYPE timeout_handler (int signal)
......
......@@ -6,34 +6,23 @@
*/
#include "config.h"
#include "fetchmail.h"
#include <stdio.h>
#include <ctype.h>
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <pwd.h>
#include <string.h>
#ifdef HAVE_NET_SOCKET_H
#include <net/socket.h>
#endif
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "fetchmail.h"
#include "getaddrinfo.h"
#include "i18n.h"
#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME)
#if defined(ENABLE_NLS)
#include <locale.h>
#endif
#ifndef HAVE_DECL_GETENV
extern char *getenv(const char *); /* needed on sysV68 R3V7.1. */
#endif
void envquery(int argc, char **argv)
/* set up basic stuff from the environment (including the rc file name) */
{
......@@ -226,7 +215,6 @@ char *rfc822timestamp(void)
static char buf[50];
time(&now);
#ifdef HAVE_STRFTIME
/*
* Conform to RFC822. We generate a 4-digit year here, avoiding
* Y2K hassles. Max length of this timestamp in an English locale
......@@ -235,24 +223,15 @@ char *rfc822timestamp(void)
* weird multibyte i18n characters (such as kanji) from showing up
* in your Received headers.
*/
#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS)
#if defined(ENABLE_NLS)
setlocale (LC_TIME, "C");
#endif
strftime(buf, sizeof(buf)-1,
"%a, %d %b %Y %H:%M:%S XXXXX (%Z)", localtime(&now));
#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS)
#if defined(ENABLE_NLS)
setlocale (LC_TIME, "");
#endif
memcpy(strstr(buf, "XXXXX"), tzoffset(&now), 5);
#else
/*
* This is really just a portability fallback, as the
* date format ctime(3) emits is not RFC822
* conformant.
*/
strlcpy(buf, ctime(&now), sizeof(buf));
buf[strlen(buf)-1] = '\0'; /* remove trailing \n */
#endif /* HAVE_STRFTIME */
return(buf);
}
......
......@@ -6,17 +6,14 @@
#include "config.h"
#ifdef ETRN_ENABLE
#include "fetchmail.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#ifdef HAVE_NET_SOCKET_H /* BeOS needs this */
#include <net/socket.h>
#endif
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
#include "i18n.h"
#include "fetchmail.h"
#include "smtp.h"
#include "socket.h"
......
......@@ -4,20 +4,15 @@
* For license terms, see the file COPYING in this directory.
*/
#include "config.h"
#include "fetchmail.h"
#include <stdio.h>
#if defined(STDC_HEADERS)
#include <stdlib.h>
#endif
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#endif
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#if defined(HAVE_SYSLOG)
#include <syslog.h>
#endif
#include <pwd.h>
#ifdef __FreeBSD__
#include <grp.h>
......@@ -25,9 +20,7 @@
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_SETRLIMIT
#include <sys/resource.h>
#endif /* HAVE_SETRLIMIT */
#ifdef HAVE_SOCKS
#include <socks.h> /* SOCKSinit() */
......@@ -37,7 +30,6 @@
#include <langinfo.h>
#endif
#include "fetchmail.h"
#include "socket.h"
#include "tunable.h"
#include "smtp.h"
......@@ -112,7 +104,7 @@ static void dropprivs(void)
}
#endif
#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME)
#if defined(ENABLE_NLS)
#include <locale.h>
/** returns timestamp in current locale,
* and resets LC_TIME locale to POSIX. */
......@@ -217,13 +209,11 @@ int main(int argc, char **argv)
*/
fm_lock_dispose();
#ifdef HAVE_GETCWD
/* save the current directory */
if (getcwd (currentwd, sizeof (currentwd)) == NULL) {
report(stderr, GT_("could not get current working directory\n"));
currentwd[0] = 0;
}
#endif
{
int i;
......@@ -346,7 +336,6 @@ int main(int argc, char **argv)
}
}
#if defined(HAVE_SYSLOG)
/* logging should be set up early in case we were restarted from exec */
if (run.use_syslog)
{
......@@ -366,7 +355,6 @@ int main(int argc, char **argv)
}
}
else
#endif
report_init((run.poll_interval == 0 || nodetach) && !run.logfile); /* when changing this, change copy above, too */
#ifdef POP3_ENABLE
......@@ -384,7 +372,6 @@ int main(int argc, char **argv)
/* construct the lockfile */
fm_lock_setup(&run);
#ifdef HAVE_SETRLIMIT
/*
* Before getting passwords, disable core dumps unless -v -d0 mode is on.
* Core dumps could otherwise contain passwords to be scavenged by a
......@@ -397,7 +384,6 @@ int main(int argc, char **argv)
corelimit.rlim_max = 0;
setrlimit(RLIMIT_CORE, &corelimit);
}
#endif /* HAVE_SETRLIMIT */
#define NETRC_FILE ".netrc"
/* parse the ~/.netrc file (if present) for future password lookups. */
......@@ -701,11 +687,9 @@ int main(int argc, char **argv)
{
report(stdout, GT_("restarting fetchmail (%s changed)\n"), rcfile);
#ifdef HAVE_GETCWD
/* restore the startup directory */
if (!currentwd[0] || chdir (currentwd) == -1)
report(stderr, GT_("attempt to re-exec may fail as directory has not been restored\n"));
#endif
/*
* Matthias Andree: Isn't this prone to introduction of
......@@ -1471,10 +1455,6 @@ static RETSIGTYPE terminate_run(int sig)
if (ctl->password)
memset(ctl->password, '\0', strlen(ctl->password));
#if !defined(HAVE_ATEXIT)
fm_lock_release();
#endif
if (activecount == 0)
exit(PS_NOMAIL);
else
......@@ -1617,10 +1597,8 @@ static void dump_params (struct runctl *runp,
printf(GT_("Logfile is %s\n"), runp->logfile);
if (strcmp(runp->idfile, IDFILE_NAME))
printf(GT_("Idfile is %s\n"), runp->idfile);
#if defined(HAVE_SYSLOG)
if (runp->use_syslog)
printf(GT_("Progress messages will be logged via syslog\n"));
#endif
if (runp->invisible)
printf(GT_("Fetchmail will masquerade and will not generate Received\n"));
if (runp->showdots)
......
......@@ -5,6 +5,7 @@
* For license terms, see the file COPYING in this directory.
*/
/* We need this for HAVE_STDARG_H, etc */
#include "config.h"
struct addrinfo;
......@@ -13,32 +14,15 @@ struct addrinfo;
#include <sys/types.h>
/* We need this for time_t */
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <sys/time.h>
#include <time.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NET_SOCKET_H
#include <net/socket.h>
#endif
#include <netdb.h>
#include <stdio.h>
/* Import Trio if needed */
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
# include "trio/trio.h"
#endif
#include "uid_db.h"
#include "fm_strl.h"
/* constants designating the various supported protocols */
......@@ -481,7 +465,6 @@ extern const char *iana_charset; /* IANA assigned charset name */
#endif
/* error.c: Error reporting */
#if defined(HAVE_STDARG_H)
void report_init(int foreground);
/** Flush partial message, suppress program name tag for next report printout. */
void report_flush(FILE *fp);
......@@ -497,12 +480,6 @@ void report_complete (FILE *fp, const char *format, ...)
void report_at_line (FILE *fp, int, const char *, unsigned int, const char *, ...)
__attribute__ ((format (printf, 5, 6)))
;
#else
void report ();
void report_build ();
void report_complete ();
void report_at_line ();
#endif
/* driver.c -- main driver loop */
void set_timeout(int);
......@@ -529,7 +506,6 @@ int readheaders(int sock,
int num,
flag *suppress_readbody);
int readbody(int sock, struct query *ctl, flag forward, int len);