#include "config.h"
#include <sys/types.h>
#define P_AUTO 1
#define P_POP2 2
#define P_POP3 3
#define P_APOP 4
#define P_RPOP 5
#define P_IMAP 6
#define P_ETRN 7
#define P_ODMR 8
#if INET6_ENABLE
#define SMTP_PORT "smtp"
#define KPOP_PORT "kpop"
#else
#define SMTP_PORT 25
#define KPOP_PORT 1109
#endif
#ifdef SSL_ENABLE
#define SIMAP_PORT 993
#define SPOP3_PORT 995
#endif
#define MAILBOX_PROTOCOL(ctl) ((ctl)->server.protocol < P_ETRN)
#define A_ANY 0
#define A_PASSWORD 1
#define A_NTLM 2
#define A_CRAM_MD5 3
#define A_OTP 4
#define A_KERBEROS_V4 5
#define A_KERBEROS_V5 6
#define A_GSSAPI 7
#define A_SSH 8
#define NO_PASSWORD(ctl) ((ctl)->server.authenticate > A_OTP || (ctl)->server.protocol == P_ETRN)
#define HOSTLEN 635
#define POPBUFSIZE 512
#define IDLEN 128
#define USERNAMELEN 128
#undef MSGBUFSIZE
#define MSGBUFSIZE 8192
#define NAMELEN 64
#define PASSWORDLEN 64
#define DIGESTLEN 33
#define PS_SUCCESS 0
#define PS_NOMAIL 1
#define PS_SOCKET 2
#define PS_AUTHFAIL 3
#define PS_PROTOCOL 4
#define PS_SYNTAX 5
#define PS_IOERR 6
#define PS_ERROR 7
#define PS_EXCLUDE 8
#define PS_LOCKBUSY 9
#define PS_SMTP 10
#define PS_DNS 11
#define PS_BSMTP 12
#define PS_MAXFETCH 13
#define PS_SERVBUSY 14
#define PS_UNDEFINED 23
#define PS_TRANSIENT 24
#define PS_REFUSED 25
#define PS_RETAINED 26
#define PS_TRUNCATED 27
#define PS_REPOLL 28
#define PS_IDLETIMEOUT 29
#define O_SILENT 0
#define O_NORMAL 1
#define O_VERBOSE 2
#define O_DEBUG 3
#define O_MONITOR O_VERBOSE
#define SIZETICKER 1024
#ifndef TRUE
#define FALSE 0
#define TRUE 1
#endif
typedef char flag;
#define FLAG_TRUE 2
#define FLAG_FALSE 1
struct runctl
{
char *logfile;
char *idfile;
int poll_interval;
char *postmaster;
flag bouncemail;
flag spambounce;
char *properties;
flag use_syslog;
flag invisible;
flag showdots;
};
struct idlist
{
unsigned char *id;
union
{
struct
{
int num;
flag mark;
#define UID_UNSEEN 0
#define UID_SEEN 1
#define UID_DELETED 2
#define UID_EXPUNGED 3
}
status;
unsigned char *id2;
} val;
struct idlist *next;
};
struct query;
struct method
{
const char *name;
#if INET6_ENABLE
const char *service;
const char *sslservice;
#else
int port;
int sslport;
#endif
flag tagged;
flag delimited;
int (*parse_response)(int, char *);
int (*getauth)(int, struct query *, char *);
int (*getrange)(int, struct query *, const char *, int *, int *, int *);
int (*getsizes)(int, int, int *);
int (*getpartialsizes)(int, int, int, int *);
int (*is_old)(int, struct query *, int);
int (*fetch_headers)(int, struct query *, int, int *);
int (*fetch_body)(int, struct query *, int, int *);
int (*trail)(int, struct query *, int);
int (*delete)(int, struct query *, int);
int (*mark_seen)(int, struct query *, int);
int (*logout_cmd)(int, struct query *);
flag retry;
};
struct hostdata
{
char *pollname;
char *via;
struct idlist *akalist;
struct idlist *localdomains;
int protocol;
#if INET6_ENABLE
char *service;
void *netsec;
#else
int port;
#endif
int interval;
int authenticate;
int timeout;
char *envelope;
int envskip;
char *qvirtual;
flag skip;
flag dns;
flag uidl;
#ifdef SDPS_ENABLE
flag sdps;
#endif
flag checkalias;
char *principal;
char *esmtp_name, *esmtp_password;
#if defined(linux) || defined(__FreeBSD__)
char *interface;
char *monitor;
int monitor_io;
struct interface_pair_s *interface_pair;
#endif
char *plugin,*plugout;
const struct method *base_protocol;
int poll_count;
char *queryname;
char *truename;
char *trueaddr;
struct hostdata *lead_server;
int esmtp_options;
};
struct query
{
struct hostdata server;
struct idlist *localnames;
int wildcard;
char *remotename;
char *password;
struct idlist *mailboxes;
struct idlist *smtphunt;
struct idlist *domainlist;
char *smtpaddress;
char *smtpname;
struct idlist *antispam;
char *mda;
char *bsmtp;
char listener;
#define SMTP_MODE 'S'
#define LMTP_MODE 'L'
char *preconnect;
char *postconnect;
flag keep;
flag fetchall;
flag flush;
flag rewrite;
flag stripcr;
flag forcecr;
flag pass8bits;
flag dropstatus;
flag dropdelivered;
flag mimedecode;
flag idle;
int limit;
int warnings;
int fetchlimit;
int fetchsizelimit;
int fastuidl;
int fastuidlcount;
int batchlimit;
int expunge;
flag use_ssl;
char *sslkey;
char *sslcert;
char *sslproto;
char *sslcertpath;
flag sslcertck;
char *sslfingerprint;
char *properties;
flag tracepolls;
flag active;
const char *destaddr;
int errcount;
int authfailcount;
int wehaveauthed;
int wehavesentauthnote;
int wedged;
char *smtphost;
int smtp_socket;
unsigned int uid;
struct idlist *skipped;
struct idlist *oldsaved, *newsaved;
struct idlist **oldsavedend;
char lastdigest[DIGESTLEN];
int mimemsg;
char digest[DIGESTLEN];
struct query *next;
};
struct msgblk
{
char *headers;
struct idlist *recipients;
char return_path[HOSTLEN + USERNAMELEN + 4];
int msglen;
int reallen;
};
#define NUM_VALUE_IN(n) (((n) == 0) ? -1 : (n))
#define NUM_VALUE_OUT(n) (((n) < 0) ? 0 : (n))
#define NUM_NONZERO(n) ((n) > 0)
#define NUM_ZERO(n) ((n) < 0)
#define NUM_SPECIFIED(n) ((n) != 0)
#define MULTIDROP(ctl) (ctl->wildcard || \
((ctl)->localnames && (ctl)->localnames->next))
#define TAGLEN 6
extern char tag[TAGLEN];
#define TAGMOD 10000
extern struct query cmd_opts, *querylist;
extern void envquery(int, char **);
extern int outlevel;
extern int yydebug;
extern int batchcount;
extern flag peek_capable;
extern struct runctl run;
extern flag nodetach;
extern flag quitmode;
extern flag check_only;
extern char *rcfile;
extern int linelimit;
extern flag versioninfo;
extern char *user;
extern char *home;
extern char *fmhome;
extern int pass;
extern flag configdump;
extern char *fetchmailhost;
extern int suppress_tags;
extern char shroud[PASSWORDLEN*2+3];
#ifdef SDPS_ENABLE
extern char *sdps_envfrom;
extern char *sdps_envto;
#endif
#if !defined __GNUC__ || __GNUC__ < 2
# define __attribute__(xyz)
#endif
#if defined(HAVE_STDARG_H)
void report_init(int foreground);
void report (FILE *fp, const char *format, ...)
__attribute__ ((format (printf, 2, 3)))
;
void report_build (FILE *fp, const char *format, ...)
__attribute__ ((format (printf, 2, 3)))
;
void report_complete (FILE *fp, const char *format, ...)
__attribute__ ((format (printf, 2, 3)))
;
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
void set_timeout(int);
int isidletimeout(void);
void resetidletimeout(void);
int do_protocol(struct query *, const struct method *);
void init_transact(const struct method *);
int readheaders(int sock,
long fetchlen,
long reallen,
struct query *ctl,
int num,
flag *suppress_readbody);
int readbody(int sock, struct query *ctl, flag forward, int len);
#if defined(HAVE_STDARG_H)
void gen_send(int sock, const char *, ... )
__attribute__ ((format (printf, 2, 3)))
;
int gen_recv(int sock, char *buf, int size);
int gen_transact(int sock, const char *, ... )
__attribute__ ((format (printf, 2, 3)))
;
#else
void gen_send();
int gen_recv();
int gen_transact();
#endif
extern struct msgblk msgblk;
void lock_setup(void), lock_assert(void);
void lock_or_die(void), lock_do_release(void);
int lock_state(void);
void lock_dispose(void);
#define GENERAL_WAIT 0
#define OPEN_WAIT 1
#define SERVER_WAIT 2
#define LISTENER_WAIT 3
#define FORWARDING_WAIT 4
extern int phase;
#define STAGE_GETAUTH 0
#define STAGE_GETRANGE 1
#define STAGE_GETSIZES 2
#define STAGE_FETCH 3
#define STAGE_IDLE 4
#define STAGE_LOGOUT 5
extern int stage;
extern int mytimeout;
#define XMIT_ACCEPT 1
#define XMIT_REJECT 2
#define XMIT_RCPTBAD 3
int interruptible_idle(int interval);
void smtp_close(struct query *, int);
int smtp_open(struct query *);
char *rcpt_address(struct query *, const char *, int);
int stuffline(struct query *, char *);
int open_sink(struct query*, struct msgblk *, int*, int*);
void release_sink(struct query *);
int close_sink(struct query *, struct msgblk *, flag);
int open_warning_by_mail(struct query *, struct msgblk *);
#if defined(HAVE_STDARG_H)
void stuff_warning(struct query *, const char *, ... )
__attribute__ ((format (printf, 2, 3)))
;
#else
void stuff_warning();
#endif
void close_warning_by_mail(struct query *, struct msgblk *);
unsigned char *reply_hack(unsigned char *, const unsigned char *, int *);
unsigned char *nxtaddr(const unsigned char *);
extern int dofastuidl;
void initialize_saved_lists(struct query *, const char *);
struct idlist *save_str(struct idlist **, const char *, flag);
void free_str_list(struct idlist **);
struct idlist *copy_str_list(struct idlist *idl);
void save_str_pair(struct idlist **, const char *, const char *);
void free_str_pair_list(struct idlist **);
int delete_str(struct idlist **, long);
struct idlist *str_in_list(struct idlist **, const char *, const flag);
int str_nr_in_list(struct idlist **, const char *);
int str_nr_last_in_list(struct idlist **, const char *);
void str_set_mark( struct idlist **, const char *, const flag);
int count_list( struct idlist **idl );
char *str_from_nr_list( struct idlist **idl, long number );
char *str_find(struct idlist **, long);
struct idlist *id_find(struct idlist **idl, long);
char *idpair_find(struct idlist **, const char *);
void append_str_list(struct idlist **, struct idlist **);
void expunge_uids(struct query *);
void uid_swap_lists(struct query *);
void uid_discard_new_list(struct query *ctl);
void uid_reset_num(struct query *ctl);
void write_saved_lists(struct query *, const char *);
int prc_parse_file(const char *, const flag);
int prc_filecheck(const char *, const flag);
void to64frombits(unsigned char *, const unsigned char *, int);
int from64tobits(char *, const char *, int maxlen);
#define MSG_IS_7BIT 0x01
#define MSG_IS_8BIT 0x02
#define MSG_NEEDS_DECODE 0x80
extern void UnMimeHeader(unsigned char *buf);
extern int MimeBodyType(unsigned char *hdrs, int WantDecode);
extern int UnMimeBodyline(unsigned char **buf, flag delimited, flag issoftline);
void interface_init(void);
void interface_parse(char *, struct hostdata *);
void interface_note_activity(struct hostdata *);
int interface_approve(struct hostdata *, flag domonitor);
#if defined(HAVE_VOIDPOINTER)
#define XMALLOCTYPE void
#else
#define XMALLOCTYPE char
#endif
XMALLOCTYPE *xmalloc(size_t);
XMALLOCTYPE *xrealloc( XMALLOCTYPE *, size_t);
char *xstrdup(const char *);
#if defined(HAVE_ALLOCA_H)
#include <alloca.h>
#else
#ifdef _AIX
#pragma alloca
#endif
#endif
#define xalloca(ptr, t, n) if (!(ptr = (t) alloca(n)))\
{report(stderr, GT_("alloca failed")); exit(PS_UNDEFINED);}
#if 0
static char *dummy = gettext_noop("alloca failed");
#endif
int doPOP2 (struct query *);
int doPOP3 (struct query *);
int doIMAP (struct query *);
int doETRN (struct query *);
int doODMR (struct query *);
int do_cram_md5(int sock, char *command, struct query *ctl, char *strip);
int do_rfc1731(int sock, char *command, char *truename);
int do_gssauth(int sock, char *command, char *hostname, char *username);
int do_otp(int sock, char *command, struct query *ctl);
extern char currentwd[1024], rcfiledir[1024];
struct query *hostalloc(struct query *);
int parsecmdline (int, char **, struct runctl *, struct query *);
char *prependdir (const char *, const char *);
char *MD5Digest (unsigned char *);
void hmac_md5 (unsigned char *, size_t, unsigned char *, size_t, unsigned char *, size_t);
int POP3_auth_rpa(unsigned char *, unsigned char *, int socket);
typedef RETSIGTYPE (*SIGHANDLERTYPE) (int);
void deal_with_sigchld(void);
RETSIGTYPE null_signal_handler(int sig);
SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler);
int daemonize(const char *, void (*)(int));
char *fm_getpassword(char *);
void escapes(const char *, char *);
char *visbuf(const char *);
const char *showproto(int);
void dump_config(struct runctl *runp, struct query *querylist);
int is_host_alias(const char *, struct query *);
char *host_fqdn(void);
char *rfc822timestamp(void);
flag isafile(int);
void yyerror(const char *);
int yylex(void);
#ifdef __EMX__
void itimerthread(void*);
#include <stdlib.h>
#include <unistd.h>
#define getcwd _getcwd2
#define chdir _chdir2
#endif
# if HAVE_STRERROR
# ifndef strerror
char *strerror ();
# endif
# endif
#define STRING_DISABLED (char *)-1
#define STRING_DUMMY ""
#ifdef NeXT
#ifndef S_IXGRP
#define S_IXGRP 0000010
#endif
#endif
#ifdef FETCHMAIL_DEBUG
#define exit(e) do { \
FILE *out; \
out = fopen("/tmp/fetchmail.log", "a"); \
fprintf(out, \
"Exiting fetchmail from file %s, line %d with status %d\n", \
__FILE__, __LINE__, e); \
fclose(out); \
_exit(e); \
} while(0)
#endif
#ifdef __CYGWIN__
#define ROOT_UID 18
#else
#define ROOT_UID 0
#endif