/* * For license terms, see the file COPYING in this directory. */ /* We need this for HAVE_STDARG_H, etc */ #include "config.h" /* constants designating the various supported protocols */ #define P_AUTO 1 #define P_POP2 2 #define P_POP3 3 #define P_IMAP 4 #define P_IMAP_K4 5 #define P_IMAP_GSS 6 #define P_APOP 7 #define P_RPOP 8 #define P_ETRN 9 #if INET6 #define SMTP_PORT "smtp" #define KPOP_PORT "kpop" #else /* INET6 */ #define SMTP_PORT 25 #define KPOP_PORT 1109 #endif /* INET6 */ /* preauthentication types */ #define A_PASSWORD 0 /* password or inline authentication */ #define A_KERBEROS_V4 1 /* preauthenticate w/ Kerberos V4 */ #define A_KERBEROS_V5 2 /* preauthenticate w/ Kerberos V5 */ /* * Definitions for buffer sizes. We get little help on setting maxima * from IMAP RFCs up to 2060, so these are mostly from POP3. */ #define HOSTLEN 635 /* max hostname length (RFC1123) */ #define POPBUFSIZE 512 /* max length of response (RFC1939) */ #define IDLEN 128 /* max length of UID (RFC1939) */ /* per RFC1939 this should be 40, but Microsoft Exchange ignores that limit */ #define USERNAMELEN 128 /* max POP3 arg length */ /* clear a netBSD kernel parameter out of the way */ #undef MSGBUFSIZE /* * The RFC822 limit on message line size is just 998. But * make this *way* oversized; idiot DOS-world mailers that * don't line-wrap properly often ship entire paragraphs as * lines. */ #define MSGBUFSIZE 8192 #define PASSWORDLEN 64 /* max password length */ #define DIGESTLEN 33 /* length of MD5 digest */ /* exit code values */ #define PS_SUCCESS 0 /* successful receipt of messages */ #define PS_NOMAIL 1 /* no mail available */ #define PS_SOCKET 2 /* socket I/O woes */ #define PS_AUTHFAIL 3 /* user authorization failed */ #define PS_PROTOCOL 4 /* protocol violation */ #define PS_SYNTAX 5 /* command-line syntax error */ #define PS_IOERR 6 /* bad permissions on rc file */ #define PS_ERROR 7 /* protocol error */ #define PS_EXCLUDE 8 /* client-side exclusion error */ #define PS_LOCKBUSY 9 /* server responded lock busy */ #define PS_SMTP 10 /* SMTP error */ #define PS_DNS 11 /* fatal DNS error */ #define PS_BSMTP 12 /* output batch could not be opened */ /* leave space for more codes */ #define PS_UNDEFINED 23 /* something I hadn't thought of */ #define PS_TRANSIENT 24 /* transient failure (internal use) */ #define PS_REFUSED 25 /* mail refused (internal use) */ #define PS_RETAINED 26 /* message retained (internal use) */ #define PS_TRUNCATED 27 /* headers incomplete (internal use) */ /* output noise level */ #define O_SILENT 0 /* mute, max squelch, etc. */ #define O_NORMAL 1 /* user-friendly */ #define O_VERBOSE 2 /* chatty */ #define O_DEBUG 3 /* prolix */ #define O_MONITOR O_VERBOSE #define SIZETICKER 1024 /* print 1 dot per this many bytes */ /* * We #ifdef this and use flag rather than bool * to avoid a type clash with curses.h */ #ifndef TRUE #define FALSE 0 #define TRUE 1 #endif /* TRUE */ typedef char flag; /* we need to use zero as a flag-uninitialized value */ #define FLAG_TRUE 2 #define FLAG_FALSE 1 struct runctl { char *logfile; char *idfile; int poll_interval; flag use_syslog; flag invisible; char *postmaster; }; struct idlist { char *id; union { struct { short num; flag mark; /* UID-index information */ #define UID_UNSEEN 0 /* hasn't been seen */ #define UID_SEEN 1 /* seen, but not deleted */ #define UID_DELETED 2 /* this message has been deleted */ #define UID_EXPUNGED 3 /* this message has been expunged */ } status; char *id2; } val; struct idlist *next; }; struct query; struct method /* describe methods for protocol state machine */ { const char *name; /* protocol name */ #if INET6 const char *service; #else /* INET6 */ int port; /* service port */ #endif /* INET6 */ flag tagged; /* if true, generate & expect command tags */ flag delimited; /* if true, accept "." message delimiter */ int (*parse_response)(int, char *); /* response_parsing function */ int (*password_canonify)(char *, char *); /* canonicalize password */ int (*getauth)(int, struct query *, char *); /* authorization fetcher */ int (*getrange)(int, struct query *, const char *, int *, int *, int *); /* get message range to fetch */ int (*getsizes)(int, int, int *); /* get sizes of messages */ int (*is_old)(int, struct query *, int); /* check for old message */ int (*fetch_headers)(int, struct query *, int, int *); /* fetch FROM headera given message */ int (*fetch_body)(int, struct query *, int, int *); /* fetch a given message */ int (*trail)(int, struct query *, int); /* eat trailer of a message */ int (*delete)(int, struct query *, int); /* delete method */ int (*logout_cmd)(int, struct query *); /* logout command */ flag retry; /* can getrange poll for new messages? */ }; struct hostdata /* shared among all user connections to given server */ { /* rc file data */ char *pollname; /* poll label of host */ char *via; /* "true" server name if non-NULL */ struct idlist *akalist; /* server name first, then akas */ struct idlist *localdomains; /* list of pass-through domains */ int protocol; /* protocol type */ #if INET6 char *service; /* IPv6 service name */ void *netsec; /* IPv6 security request */ #else /* INET6 */ int port; /* TCP/IP service port number */ #endif /* INET6 */ int interval; /* # cycles to skip between polls */ int preauthenticate; /* preauthentication mode to try */ int timeout; /* inactivity timout in seconds */ char *envelope; /* envelope address list header */ int envskip; /* skip to numbered envelope header */ char *qvirtual; /* prefix removed from local user id */ flag skip; /* suppress poll in implicit mode? */ flag dns; /* do DNS lookup on multidrop? */ flag uidl; /* use RFC1725 UIDLs? */ #ifdef SDPS_ENABLE flag sdps; /* use Demon Internet SDPS *ENV */ #endif /* SDPS_ENABLE */ flag checkalias; /* resolve aliases by comparing IPs? */ #ifdef linux char *interface; char *monitor; int monitor_io; struct interface_pair_s *interface_pair; #endif /* linux */ char *plugin,*plugout; /* computed for internal use */ const struct method *base_protocol; /* relevant protocol method table */ int poll_count; /* count of polls so far */ char *queryname; /* name to attempt DNS lookup on */ char *truename; /* "true name" of server host */ struct hostdata *lead_server; /* ptr to lead query for this server */ int esmtp_options; }; struct query { /* mailserver connection controls */ struct hostdata server; /* per-user data */ struct idlist *localnames; /* including calling user's name */ int wildcard; /* should unmatched names be passed through */ char *remotename; /* remote login name to use */ char *password; /* remote password to use */ struct idlist *mailboxes; /* list of mailboxes to check */ /* per-forwarding-target data */ struct idlist *smtphunt; /* list of SMTP hosts to try forwarding to */ char *smtpaddress; /* address to force in RCPT TO */ struct idlist *antispam; /* list of listener's antispam response */ char *mda; /* local MDA to pass mail to */ char *bsmtp; /* BSMTP output file */ char listener; /* what's the listener's wire protocol? */ #define SMTP_MODE 'S' #define LMTP_MODE 'L' char *preconnect; /* pre-connection command to execute */ char *postconnect; /* post-connection command to execute */ /* per-user control flags */ flag keep; /* if TRUE, leave messages undeleted */ flag fetchall; /* if TRUE, fetch all (not just unseen) */ flag flush; /* if TRUE, delete messages already seen */ flag rewrite; /* if TRUE, canonicalize recipient addresses */ flag stripcr; /* if TRUE, strip CRs in text */ flag forcecr; /* if TRUE, force CRs before LFs in text */ flag pass8bits; /* if TRUE, ignore Content-Transfer-Encoding */ flag dropstatus; /* if TRUE, drop Status lines in mail */ flag mimedecode; /* if TRUE, decode MIME-armored messages */ int limit; /* limit size of retrieved messages */ int warnings; /* size warning interval */ int fetchlimit; /* max # msgs to get in single poll */ int batchlimit; /* max # msgs to pass in single SMTP session */ int expunge; /* max # msgs to pass between expunges */ char *properties; /* passthrough properties for extensions */ /* internal use -- per-poll state */ flag active; /* should we actually poll this server? */ const char *destaddr; /* destination host for this query */ int errcount; /* count transient errors in last pass */ int wedged; /* wedged by auth failures or timeouts? */ char *smtphost; /* actual SMTP host we connected to */ int smtp_socket; /* socket descriptor for SMTP connection */ unsigned int uid; /* UID of user to deliver to */ struct idlist *skipped; /* messages skipped on the mail server */ struct idlist *oldsaved, *newsaved; /* internal use -- per-message state */ int mimemsg; /* bitmask indicating MIME body-type */ char digest [D
dnl Autoconfigure input file for fetchmail
dnl Eric S. Raymond <esr@thyrsus.com>
dnl
dnl Process this file with autoconf to produce a configure script.
dnl

AC_INIT(fetchmail.h)		dnl A distinctive file to look for in srcdir. 
AC_CONFIG_HEADER(config.h)

dnl We want these before the checks, so the checks can modify their values.
test -z "$CFLAGS" && CFLAGS=-O AC_SUBST(CFLAGS)
test -z "$LDFLAGS" && LDFLAGS=-s AC_SUBST(LDFLAGS)

AC_CANONICAL_HOST
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_CPP			dnl Later checks need this.
AC_PROG_CC_C_O
AC_AIX
AC_ISC_POSIX
AC_MINIX
AC_HEADER_STDC
AC_TYPE_SIZE_T
AC_TYPE_PID_T
AC_TYPE_SIGNAL
AC_CHECK_HEADERS(unistd.h termios.h termio.h sgtty.h stdarg.h alloca.h sys/itimer.h fcntl.h sys/fcntl.h memory.h) 

AC_C_CONST			dnl getopt needs this.

AC_PROG_LEX
AC_PROG_YACC
AC_SUBST(LIBOBJS)

# Under sysV68, socket and friends are provided by the C library.
# -linet does not provide socket, but causes multiple definition
# errors at link-time.  It is thus better to only use the C library.
# So don't add -linet to the link list unless it's necessary
AC_CHECK_FUNC(socket,
    AC_MSG_RESULT(using libc's socket),
    AC_CHECK_LIB(socket,socket)
    AC_CHECK_LIB(inet,socket))

# The condition in this test copes with the presence of inet_addr in libc6.
AC_CHECK_FUNC(inet_addr,
    AC_MSG_RESULT(using libc's inet_addr),
    AC_CHECK_LIB(nsl,inet_addr))

AC_CHECK_LIB(opie,opiegenerator)

dnl Port hack for Interactive UNIX System V/386 Release 3.2
AC_CHECK_LIB(cposix, strchr,
		[EXTRADEFS="$EXTRADEFS -D_SYSV3"
		LIBS="$LIBS -lcposix"])

AC_CHECK_FUNC(strstr, AC_DEFINE(HAVE_STRSTR), 
              [EXTRASRC="$EXTRASRC \$(srcdir)/strstr.c"
               EXTRAOBJ="$EXTRAOBJ strstr.o"])

AC_CHECK_FUNC(strcasecmp, AC_DEFINE(HAVE_STRCASECMP), 
              [EXTRASRC="$EXTRASRC \$(srcdir)/strcasecmp.c"
               EXTRAOBJ="$EXTRAOBJ strcasecmp.o"])
             
AC_CHECK_FUNC(getopt_long, AC_DEFINE(HAVE_GETOPTLONG),
              [EXTRASRC="$EXTRASRC \$(srcdir)/getopt.c \$(srcdir)/getopt1.c"
               EXTRAOBJ="$EXTRAOBJ getopt.o getopt1.o"])

AC_FUNC_VPRINTF
AC_FUNC_ALLOCA
if test -n "$ALLOCA" 
then
  EXTRASRC="$EXTRASRC \$(srcdir)/alloca.c"
  EXTRAOBJ="$EXTRAOBJ alloca.o"
fi

dnl All AC_CHECK_FUNCs must precede the following AC_SUBSTs

AC_SUBST(EXTRADEFS)
AC_SUBST(EXTRASRC)
AC_SUBST(EXTRAOBJ)

AC_CHECK_FUNCS(tcsetattr stty setsid s