1
/** \file fetchmail.h  header file for fetchmail */
2
#ifndef _FETCHMAIL_H
3
#define _FETCHMAIL_H
4
/*
5
 * For license terms, see the file COPYING in this directory.
6
 */
7
8
/* We need this for HAVE_STDARG_H, etc */
9
#include "config.h"
10
11
struct addrinfo;
12
13
/* We need this for size_t */
14
#include <sys/types.h>
15
16
/* We need this for time_t */
17
#if TIME_WITH_SYS_TIME
18
# include <sys/time.h>
19
# include <time.h>
20
#else
21
# if HAVE_SYS_TIME_H
22
#  include <sys/time.h>
23
# else
24
#  include <time.h>
25
# endif
26
#endif
27
28
#ifdef HAVE_SYS_SOCKET_H
29
#include <sys/socket.h>
30
#endif
31
#ifdef HAVE_NET_SOCKET_H
32
#include <net/socket.h>
33
#endif
34
#include <netdb.h>
35
#include <stdio.h>
36
37
/* Import Trio if needed */
38
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
39
#  include "trio/trio.h"
40
#endif
41
42
/* We need this for strstr */
43
#if !defined(HAVE_STRSTR) && !defined(strstr)
44
char *strstr(const char *, const char *);
45
#endif
46
47
#include "fm_strl.h"
48
49
/* constants designating the various supported protocols */
50
#define		P_AUTO		1
51
#define		P_POP2		2
52
#define		P_POP3		3
53
#define		P_APOP		4
54
#define		P_RPOP		5
55
#define		P_IMAP		6
56
#define		P_ETRN		7
57
#define		P_ODMR		8
58
59
#define		SMTP_PORT	"smtp"
60
#define		SMTP_PORT_NUM	25
61
#define		KPOP_PORT	"kpop"
62
63
#ifdef SSL_ENABLE
64
#define		SIMAP_PORT	993
65
#define		SPOP3_PORT	995
66
#endif
67
68
/* 
69
 * We need to distinguish between mailbox and mailbag protocols.
70
 * Under a mailbox protocol wwe're pulling mail for a speecific user.
71
 * Under a mailbag protocol we're fetching mail for an entire domain.
72
 */
73
#define MAILBOX_PROTOCOL(ctl)	((ctl)->server.protocol < P_ETRN)
74
75
/* authentication types */
76
#define		A_ANY		0	/* use the first method that works */
77
#define		A_PASSWORD	1	/* password authentication */
78
#define		A_NTLM		2	/* Microsoft NTLM protocol */
79
#define		A_CRAM_MD5	3	/* CRAM-MD5 shrouding (RFC2195) */
80
#define		A_OTP		4	/* One-time password (RFC1508) */
81
#define		A_KERBEROS_V4	5	/* authenticate w/ Kerberos V4 */
82
#define		A_KERBEROS_V5	6	/* authenticate w/ Kerberos V5 */
83
#define 	A_GSSAPI	7	/* authenticate with GSSAPI */
84
#define		A_SSH		8	/* authentication at session level */
85
#define		A_MSN		9	/* same as NTLM with keyword MSN */
86
#define		A_EXTERNAL	10	/* external authentication (client cert) */
87
88
/* some protocols or authentication types (KERBEROS, GSSAPI, SSH) don't
89
 * require a password */
90
#define NO_PASSWORD(ctl) \
91
    ((ctl)->server.authenticate == A_OTP \
92
     || (ctl)->server.authenticate == A_KERBEROS_V4 \
93
     || (ctl)->server.authenticate == A_KERBEROS_V5 \
94
     || (ctl)->server.authenticate == A_GSSAPI \
95
     || (ctl)->server.authenticate == A_SSH \
96
     || (ctl)->server.authenticate == A_EXTERNAL \
97
     || (ctl)->server.protocol == P_ETRN)
98
99
/*
100
 * Definitions for buffer sizes.  We get little help on setting maxima
101
 * from IMAP RFCs up to 2060, so these are mostly from POP3.
102
 */
103
#define		HOSTLEN		635	/* max hostname length (RFC1123) */
104
#define		POPBUFSIZE	512	/* max length of response (RFC1939) */
105
#define		IDLEN		128	/* max length of UID (RFC1939) */
106
107
/* per RFC1939 this should be 40, but Microsoft Exchange ignores that limit */
108
#define		USERNAMELEN	128	/* max POP3 arg length */
109
110
/* clear a netBSD kernel parameter out of the way */ 
111
#undef		MSGBUFSIZE
112
113
/*
114
 * The RFC822 limit on message line size is just 998.  But
115
 * make this *way* oversized; idiot DOS-world mailers that
116
 * don't line-wrap properly often ship entire paragraphs as
117
 * lines.
118
 */
119
#define		MSGBUFSIZE	8192
120
121
#define		NAMELEN		64	/* max username length */
122
#define		PASSWORDLEN	64	/* max password length */
123
#define		DIGESTLEN	33	/* length of MD5 digest */
124
125
/* exit code values */
126
/* NOTE THAT PS_SUCCESS MUST ALWAYS BE 0 - SOME PARTS OF THE CODE
127
 * RELY ON THIS VALUE! */
128
#define		PS_SUCCESS	0	/* successful receipt of messages */
129
#define		PS_NOMAIL       1	/* no mail available */
130
#define		PS_SOCKET	2	/* socket I/O woes */
131
#define		PS_AUTHFAIL	3	/* user authorization failed */
132
#define		PS_PROTOCOL	4	/* protocol violation */
133
#define		PS_SYNTAX	5	/* command-line syntax error */
134
#define		PS_IOERR	6	/* bad permissions on rc file */
135
#define		PS_ERROR	7	/* protocol error */
136
#define		PS_EXCLUDE	8	/* client-side exclusion error */
137
#define		PS_LOCKBUSY	9	/* server responded lock busy */
138
#define		PS_SMTP         10      /* SMTP error */
139
#define		PS_DNS		11	/* fatal DNS error */
140
#define		PS_BSMTP	12	/* output batch could not be opened */
141
#define		PS_MAXFETCH	13	/* poll ended by fetch limit */
142
#define		PS_SERVBUSY	14	/* server is busy */
143
/* leave space for more codes */
144
#define		PS_UNDEFINED	23	/* something I hadn't thought of */
145
#define		PS_TRANSIENT	24	/* transient failure (internal use) */
146
#define		PS_REFUSED	25	/* mail refused (internal use) */
147
#define		PS_RETAINED	26	/* message retained (internal use) */
148
#define		PS_REPOLL	28	/* repoll immediately with changed parameters (internal use) */
149
#define		PS_IDLETIMEOUT	29	/* timeout on imap IDLE (internal use) */
150
#define		PS_UNTAGGED	30	/* untagged response on imap command (internal use) */
151
152
/* output noise level */
153
#define         O_SILENT	0	/* mute, max squelch, etc. */
154
#define		O_NORMAL	1	/* user-friendly */
155
#define		O_VERBOSE	2	/* chatty */
156
#define		O_DEBUG		3	/* prolix */
157
#define		O_MONITOR	O_VERBOSE
158
159
#define		SIZETICKER	1024	/* print 1 dot per this many bytes */
160
161
/*
162
 * We #ifdef this and use flag rather than bool
163
 * to avoid a type clash with curses.h
164
 */
165
#ifndef TRUE
166
#define FALSE	0
167
#define TRUE	1
168
#endif /* TRUE */
169
typedef	char	flag;
170
171
/* we need to use zero as a flag-uninitialized value */
172
#define FLAG_TRUE	2
173
#define FLAG_FALSE	1
174
175
/** run control data */
176
struct runctl
177
{
178
    char	*logfile;	/** where to write log information */
179
    char	*idfile;	/** where to store UID data */
180
    char	*pidfile;	/** where to record the PID of daemon mode processes */
181
    const char	*postmaster;
182
    char	*properties;
183
    int		poll_interval;	/** poll interval in seconds (daemon mode, 0 == off) */
184
    flag	bouncemail;
185
    flag	spambounce;
186
    flag	softbounce;
187
    flag	use_syslog;
188
    flag	invisible;
189
    flag	showdots;
190
};
191
192
/** \name idlist */
193
/** Dual-use entry of singly-linked list for storing id/status or id/id2
194
 * pairs. */
195
struct idlist
196
{
197
    char *id;	/**< key */
198
    union
199
    {
200
	struct
201
	{
202
	    int		num;
203
	    flag	mark;		/**< UID-index information */
204
        }
205
	status;				/**< value for id/status pairs */
206
	char *id2;			/**< value for id/id2 pairs */
207
    } val;				/**< union to store value for key \a id */
208
    struct idlist *next;		/**< pointer to next list element */
209
};
210
211
/** List of possible values for idlist::mark */
212
enum {
213
UID_UNSEEN=	0,		/**< id hasn't been seen */
214
UID_SEEN=	1,		/**< id was seen, but not deleted */
215
UID_DELETED=	2,		/**< this message has been marked deleted */
216
UID_EXPUNGED=	3		/**< this message has been expunged */
217
};
218
/*@}*/
219
220
221
struct query;
222
223
struct method		/* describe methods for protocol state machine */
224
{
225
    const char *name;		/* protocol name */
226
    const char *service;	/* service port (unencrypted) */
227
    const char *sslservice;	/* service port (SSL) */
228
    flag tagged;		/* if true, generate & expect command tags */
229
    flag delimited;		/* if true, accept "." message delimiter */
230
    int (*parse_response)(int, char *);
231
				/* response_parsing function */
232
    int (*getauth)(int, struct query *, char *);
233
				/* authorization fetcher */
234
    int (*getrange)(int, struct query *, const char *, int *, int *, int *);
235
				/* get message range to fetch */
236
    int (*getsizes)(int, int, int *);
237
				/* get sizes of messages */
238
    int (*getpartialsizes)(int, int, int, int *);
239
				/* get sizes of subset of messages */
240
    int (*is_old)(int, struct query *, int);
241
				/* check for old message */
242
    int (*fetch_headers)(int, struct query *, int, int *);
243
				/* fetch header from a given message */
244
    int (*fetch_body)(int, struct query *, int, int *);
245
				/* fetch a given message */
246
    int (*trail)(int, struct query *, const char *);
247
				/* eat trailer of a message */
248
    int (*delete_msg)(int, struct query *, int);
249
				/* delete method */
250
    int (*mark_seen)(int, struct query *, int);
251
				/* mark as seen method */
252
    int (*end_mailbox_poll)(int, struct query *);
253
				/* end-of-mailbox processing */
254
    int (*logout_cmd)(int, struct query *);
255
				/* logout command */
256
    flag retry;			/* can getrange poll for new messages? */
257
};
258
259
enum badheader { BHREJECT = 0, BHACCEPT };
260
261
struct hostdata		/* shared among all user connections to given server */
262
{
263
    /* rc file data */
264
    char *pollname;			/* poll label of host */
265
    char *via;				/* "true" server name if non-NULL */
266
    struct idlist *akalist;		/* server name first, then akas */
267
    struct idlist *localdomains;	/* list of pass-through domains */
268
    int protocol;			/* protocol type */
269
    const char *service;		/* service name */
270
    int interval;			/* # cycles to skip between polls */
271
    int authenticate;			/* authentication mode to try */
272
    int timeout;			/* inactivity timout in seconds */
273
    char *envelope;			/* envelope address list header */
274
    int envskip;			/* skip to numbered envelope header */
275
    char *qvirtual;			/* prefix removed from local user id */
276
    flag skip;				/* suppress poll in implicit mode? */
277
    flag dns;				/* do DNS lookup on multidrop? */
278
    flag uidl;				/* use RFC1725 UIDLs? */
279
#ifdef SDPS_ENABLE
280
    flag sdps;				/* use Demon Internet SDPS *ENV */
281
#endif /* SDPS_ENABLE */
282
    flag checkalias;			/* resolve aliases by comparing IPs? */
283
    flag tracepolls;			/* if TRUE, add poll trace info to Received */
284
    char *principal;			/* Kerberos principal for mail service */
285
    char *esmtp_name, *esmtp_password;	/* ESMTP AUTH information */
286
    enum badheader badheader;		/* bad-header {pass|reject} */
287
288
#if defined(linux) || defined(__FreeBSD__)
289
#define CAN_MONITOR
290
#endif
291
292
#ifdef CAN_MONITOR
293
    char *interface;
294
    char *monitor;
295
    int  monitor_io;
296
    struct interface_pair_s *interface_pair;
297
#endif
298
299
    char *plugin,*plugout;
300
301
    /* computed for internal use */
302
    const struct method *base_protocol;	/* relevant protocol method table */
303
    int poll_count;			/* count of polls so far */
304
    char *queryname;			/* name to attempt DNS lookup on */
305
    char *truename;			/* "true name" of server host */
306
    struct sockaddr *trueaddr;		/* IP address of truename */
307
    size_t trueaddr_len;		/* size of trueaddr data */
308
    struct hostdata *lead_server;	/* ptr to lead query for this server */
309
    int esmtp_options;
310
    int workarounds;			/* track which workarounds the user was warned about */
311
};
312
313
/*
314
 * bit flags to set in workarounds after the corresponding warning,
315
 * which we assume to be server-specific, has been printed,
316
 * so we don't spam our users in daemon mode.
317
 */
318
#define WKA_TOP (1L << 0)		/* Maillennium TOP -> RETR override warning */
319
320
struct query
321
{
322
    /* mailserver connection controls */
323
    struct hostdata server;
324
325
    /* per-user data */
326
    struct idlist *localnames;	/* including calling user's name */
327
    int wildcard;		/* should unmatched names be passed through */
328
    char *remotename;		/* remote login name to use */
329
    char *password;		/* remote password to use */
330
    struct idlist *mailboxes;	/* list of mailboxes to check */
331
332
    /* per-forwarding-target data */
333
    struct idlist *smtphunt;	/* list of SMTP hosts to try forwarding to */
334
    struct idlist *domainlist;	/* domainlist to fetch from */
335
    char *smtpaddress;		/* address to force in RCPT TO */ 
336
    char *smtpname;             /* full RCPT TO name, including domain */
337
    struct idlist *antispam;	/* list of listener's antispam response */
338
    const char *mda;		/* local MDA to pass mail to */
339
    char *bsmtp;		/* BSMTP output file */
340
    char listener;		/* what's the listener's wire protocol? */
341
#define SMTP_MODE	'S'
342
#define LMTP_MODE	'L'
343
    char *preconnect;		/* pre-connection command to execute */
344
    char *postconnect;		/* post-connection command to execute */
345
346
    /* per-user control flags */
347
    flag keep;			/* if TRUE, leave messages undeleted */
348
    flag fetchall;		/* if TRUE, fetch all (not just unseen) */
349
    flag flush;			/* if TRUE, delete messages already seen */
350
    flag limitflush;		/* if TRUE, delete oversized mails */
351
    flag rewrite;		/* if TRUE, canonicalize recipient addresses */
352
    flag stripcr;		/* if TRUE, strip CRs in text */
353
    flag forcecr;		/* if TRUE, force CRs before LFs in text */
354
    flag pass8bits;		/* if TRUE, ignore Content-Transfer-Encoding */
355
    flag dropstatus;		/* if TRUE, drop Status lines in mail */
356
    flag dropdelivered;         /* if TRUE, drop Delivered-To lines in mail */
357
    flag mimedecode;		/* if TRUE, decode MIME-armored messages */
358
    flag idle;			/* if TRUE, idle after each poll */
359
    int	limit;			/* limit size of retrieved messages */
360
    int warnings;		/* size warning interval */
361
    int	fetchlimit;		/* max # msgs to get in single poll */
362
    int fetchsizelimit;		/* max # msg sizes to get in a request */
363
    int fastuidl;		/* do binary search for new UIDLs? */
364
    int fastuidlcount;		/* internal count for frequency of binary search */
365
    int	batchlimit;		/* max # msgs to pass in single SMTP session */
366
    int	expunge;		/* max # msgs to pass between expunges */
367
    flag use_ssl;		/* use SSL encrypted session */
368
    char *sslkey;		/* optional SSL private key file */
369
    char *sslcert;		/* optional SSL certificate file */
370
    char *sslproto;		/** force transport protocol (ssl2|ssl3|ssl23|tls1) - if NULL,
371
				  use ssl23 for SSL and opportunistic tls1 for non-SSL connections. */
372
    char *sslcertfile;		/* Trusted certificate file for checking the server cert */
373
    char *sslcertpath;		/* Trusted certificate directory for checking the server cert */
374
    flag sslcertck;		/* Strictly check the server cert. */
375
    char *sslcommonname;	/* CommonName to expect from server */
376
    char *sslfingerprint;	/* Fingerprint to check against */
377
    char *properties;		/* passthrough properties for extensions */
378
379
    /* internal use -- per-poll state */
380
    flag active;		/* should we actually poll this server? */
381
    char *destaddr;		/* destination host for this query */
382
    int errcount;		/* count transient errors in last pass */
383
    int authfailcount;		/* count of authorization failures */
384
    int wehaveauthed;		/* We've managed to logon at least once! */
385
    int wehavesentauthnote;	/* We've sent an authorization failure note */
386
    int wedged;			/* wedged by auth failures or timeouts? */
387
    char *smtphost;		/* actual SMTP host we connected to */
388
    char smtphostmode;		/* what's the actual SMTP host's wire protocol? */
389
    int smtp_socket;		/* socket descriptor for SMTP connection */
390
    unsigned int uid;		/* UID of user to deliver to */
391
    struct idlist *skipped;	/* messages skipped on the mail server */
392
    struct idlist *oldsaved, *newsaved;
393
    struct idlist **oldsavedend;
394
    char lastdigest[DIGESTLEN];	/* last MD5 hash seen on this connection */
395
    char *folder;		/* folder currently being polled */
396
397
    /* internal use -- per-message state */
398
    int mimemsg;		/* bitmask indicating MIME body-type */
399
    unsigned char digest[DIGESTLEN];	/* md5 digest buffer */
400
401
    /* internal use -- housekeeping */
402
    struct query *next;		/* next query control block in chain */
403
};
404
405
struct msgblk			/** message header parsed for open_sink() */
406
{
407
    char   		*headers;	/**< raw message headers */
408
    struct idlist	*recipients;	/**< addressees */
409
    char		return_path[HOSTLEN + USERNAMELEN + 4]; /**< envelope sender */
410
    int			msglen;
411
    int			reallen;
412
};
413
414
415
/*
416
 * Numeric option handling.  Numeric option value of zero actually means
417
 * it's unspecified.  Value less than zero is zero.  The reason for this
418
 * screwy encoding is so we can zero out an option block in order to set the
419
 * numeric flags in it to unspecified.
420
 */
421
#define NUM_VALUE_IN(n)		(((n) == 0) ? -1 : (n))
422
#define NUM_VALUE_OUT(n)	(((n) < 0) ? 0 : (n))
423
#define NUM_NONZERO(n)		((n) > 0)
424
#define NUM_ZERO(n)		((n) < 0)
425
#define NUM_SPECIFIED(n)	((n) != 0)
426
427
#define MULTIDROP(ctl)		((ctl)->wildcard || \
428
				 ((ctl)->localnames && (ctl)->localnames->next))
429
430
/*
431
 * Note: tags are generated with an a%04d format from a 1-origin
432
 * integer sequence number.  Length 4 permits transaction numbers
433
 * up to 9999, so we force rollover with % 10000.  There's no special
434
 * reason for this format other than to look like the exmples in the
435
 * IMAP RFCs.
436
 */
437
#define TAGLEN	6		/* 'a' + 4 digits + NUL */
438
extern char tag[TAGLEN];
439
#define TAGMOD	10000
440
441
/* list of hosts assembled from run control file and command line */
442
extern struct query cmd_opts, *querylist;
443
444
/* what's returned by envquery */
445
extern void envquery(int, char **);
446
447
/* controls the detail level of status/progress messages written to stderr */
448
extern int outlevel;    	/* see the O_.* constants above */
449
extern int yydebug;		/* enable parse debugging */
450
451
/* these get computed */
452
extern int batchcount;		/* count of messages sent in current batch */
453
extern flag peek_capable;	/* can we read msgs without setting seen? */
454
455
/* miscellaneous global controls */
456
extern struct runctl run;	/* global controls for this run */
457
extern flag nodetach;		/* if TRUE, don't detach daemon process */
458
extern flag quitmode;		/* if --quit was set */
459
extern int  quitind;		/* optind after position of last --quit option */
460
extern flag check_only;		/* if --check was set */
461
extern char *rcfile;		/* path name of rc file */
462
extern int linelimit;		/* limit # lines retrieved per site */
463
extern flag versioninfo;	/* emit only version info */
464
extern char *user;		/* name of invoking user */
465
extern char *home;		/* home directory of invoking user */
466
extern char *fmhome;		/* fetchmail home directory */
467
extern int pass;		/* number of re-polling pass */
468
extern flag configdump;		/* dump control blocks as Python dictionary */
469
extern const char *fetchmailhost; /* either "localhost" or an FQDN */
470
extern int suppress_tags;	/* suppress tags in tagged protocols? */
471
extern char shroud[PASSWORDLEN*2+3];	/* string to shroud in debug output */
472
#ifdef SDPS_ENABLE
473
extern char *sdps_envfrom;
474
extern char *sdps_envto;
475
#endif /* SDPS_ENABLE */
476
477
extern const char *iana_charset;	/* IANA assigned charset name */
478
479
/* from/for ucs/norm_charmap.c */
480
#include "ucs/norm_charmap.h"
481
482
/* prototypes for globally callable functions */
483
484
/* from /usr/include/sys/cdefs.h */
485
#if !defined __GNUC__ || __GNUC__ < 2
486
# define __attribute__(xyz)    /* Ignore. */
487
#endif
488
489
/* error.c: Error reporting */
490
#if defined(HAVE_STDARG_H)
491
void report_init(int foreground);
492
 /** Flush partial message, suppress program name tag for next report printout. */
493
void report_flush(FILE *fp);
494
void report (FILE *fp, const char *format, ...)
495
    __attribute__ ((format (printf, 2, 3)))
496
    ;
497
void report_build (FILE *fp, const char *format, ...)
498
    __attribute__ ((format (printf, 2, 3)))
499
    ;
500
void report_complete (FILE *fp, const char *format, ...)
501
    __attribute__ ((format (printf, 2, 3)))
502
    ;
503
void report_at_line (FILE *fp, int, const char *, unsigned int, const char *, ...)
504
    __attribute__ ((format (printf, 5, 6)))
505
    ;
506
#else
507
void report ();
508
void report_build ();
509
void report_complete ();
510
void report_at_line ();
511
#endif
512
513
/* driver.c -- main driver loop */
514
void set_timeout(int);
515
int is_idletimeout(void);
516
void resetidletimeout(void);
517
int do_protocol(struct query *, const struct method *);
518
519
/* transact.c: transaction support */
520
/** \ingroup gen_recv_split
521
 * Data structure to cache data between \func gen_recv_split calls,
522
 * must be initialized before use by calling \func gen_recv_split_init. */
523
struct RecvSplit
524
{
525
    char prefix[100];		/**< prefix to match/repeat when splitting lines */
526
    int cached;			/**< flag to record if we have data cached in \a buf */
527
    char buf[MSGBUFSIZE];	/**< buffer for cached data */
528
};
529
530
void init_transact(const struct method *);
531
int readheaders(int sock,
532
		       long fetchlen,
533
		       long reallen,
534
		       struct query *ctl,
535
		       int num,
536
		       flag *suppress_readbody);
537
int readbody(int sock, struct query *ctl, flag forward, int len);
538
#if defined(HAVE_STDARG_H)
539
void gen_send(int sock, const char *, ... )
540
    __attribute__ ((format (printf, 2, 3)))
541
    ;
542
int gen_recv(int sock, char *buf, int size);
543
void gen_recv_split_init(const char *prefix, struct RecvSplit *rs);
544
int gen_recv_split(int sock, char *buf, int size, struct RecvSplit *rs);
545
int gen_transact(int sock, const char *, ... )
546
    __attribute__ ((format (printf, 2, 3)))
547
    ;
548
#else
549
void gen_send();
550
int gen_recv();
551
void gen_recv_split_init();
552
int gen_recv_split();
553
int gen_transact();
554
#endif
555
extern struct msgblk msgblk;
556
557
/* use these to track what was happening when the nonresponse timer fired */
558
#define GENERAL_WAIT	0	/* unknown wait type */
559
#define OPEN_WAIT	1	/* waiting from mailserver open */
560
#define SERVER_WAIT	2	/* waiting for mailserver response */
561
#define LISTENER_WAIT	3	/* waiting for listener initialization */
562
#define FORWARDING_WAIT	4	/* waiting for listener response */
563
extern int phase;
564
565
/* response hooks can use this to identify the query stage */
566
#define STAGE_GETAUTH	0
567
#define STAGE_GETRANGE	1
568
#define STAGE_GETSIZES	2
569
#define STAGE_FETCH	3
570
#define STAGE_IDLE	4
571
#define STAGE_LOGOUT	5
572
extern int stage;
573
574
extern int mytimeout;
575
576
/* mark values for name lists */
577
#define XMIT_ACCEPT	1	/* accepted; matches local domain or name */
578
#define XMIT_REJECT	2	/* rejected; no match */
579
#define XMIT_RCPTBAD	3	/* SMTP listener rejected the name */ 
580
581
/* idle.c */
582
int interruptible_idle(int interval);
583
extern volatile int lastsig;
584
585
/* sink.c: forwarding */
586
void smtp_close(struct query *, int);
587
int smtp_open(struct query *);
588
int smtp_setup(struct query *);
589
char *rcpt_address(struct query *, const char *, int);
590
int stuffline(struct query *, char *);
591
int open_sink(struct query*, struct msgblk *, int*, int*);
592
void release_sink(struct query *);
593
int close_sink(struct query *, struct msgblk *, flag);
594
int open_warning_by_mail(struct query *);
595
#if defined(HAVE_STDARG_H)
596
void stuff_warning(const char *, struct query *, const char *, ... )
597
    __attribute__ ((format (printf, 3, 4)))
598
    ;
599
#else
600
void stuff_warning();
601
#endif
602
void close_warning_by_mail(struct query *, struct msgblk *);
603
604
/* rfc822.c: RFC822 header parsing */
605
char *reply_hack(char *, const char *, size_t *);
606
char *nxtaddr(const char *);
607
608
/* uid.c: UID support */
609
extern int dofastuidl;
610
void initialize_saved_lists(struct query *hostlist, const char *idfile);
611
void expunge_uids(struct query *ctl);
612
void uid_swap_lists(struct query *ctl);
613
void uid_discard_new_list(struct query *ctl);
614
void uid_reset_num(struct query *ctl);
615
void write_saved_lists(struct query *hostlist, const char *idfile);
616
617
/* idlist.c */
618
struct idlist *save_str(struct idlist **idl, const char *str, flag status);
619
void free_str_list(struct idlist **idl);
620
void save_str_pair(struct idlist **idl, const char *str1, const char *str2);
621
struct idlist *str_in_list(struct idlist **idl, const char *str, const flag caseblind);
622
int str_nr_in_list(struct idlist **idl, const char *str);
623
int str_nr_last_in_list(struct idlist **idl, const char *str);
624
void str_set_mark(struct idlist **idl, const char *str, const flag val);
625
int count_list(struct idlist **idl);
626
char *str_from_nr_list(struct idlist **idl, long number);
627
char *str_find(struct idlist **idl, long number);
628
struct idlist *id_find(struct idlist **idl, long number);
629
char *idpair_find(struct idlist **idl, const char *id);
630
int delete_str(struct idlist **idl, long num);
631
struct idlist *copy_str_list(struct idlist *idl);
632
void append_str_list(struct idlist **idl, struct idlist **nidl);
633
634
/* rcfile_y.y */
635
int prc_parse_file(const char *, const flag);
636
int prc_filecheck(const char *, const flag);
637
638
/* base64.c */
639
void to64frombits(char *, const void *, int);
640
int from64tobits(void *, const char *, int maxlen);
641
642
/* unmime.c */
643
/* Bit-mask returned by MimeBodyType */
644
#define MSG_IS_7BIT       0x01
645
#define MSG_IS_8BIT       0x02
646
#define MSG_NEEDS_DECODE  0x80
647
extern void UnMimeHeader(char *buf);
648
extern int  MimeBodyType(char *hdrs, int WantDecode);
649
extern int  UnMimeBodyline(char **buf, flag delimited, flag issoftline);
650
651
/* interface.c */
652
void interface_init(void);
653
void interface_parse(char *, struct hostdata *);
654
void interface_note_activity(struct hostdata *);
655
int interface_approve(struct hostdata *, flag domonitor);
656
657
#include "xmalloc.h"
658
659
/* protocol driver and methods */
660
int doPOP2 (struct query *); 
661
int doPOP3 (struct query *);
662
int doIMAP (struct query *);
663
int doETRN (struct query *);
664
int doODMR (struct query *);
665
666
/* authentication functions */
667
int do_cram_md5(int sock, const char *command, struct query *ctl, const char *strip);
668
int do_rfc1731(int sock, const char *command, const char *truename);
669
int check_gss_creds(const char *service, const char *hostname);
670
int do_gssauth(int sock, const char *command, const char *service, const char *hostname, const char *username);
671
int do_otp(int sock, const char *command, struct query *ctl);
672
673
/* miscellanea */
674
675
/* these should be of size PATH_MAX */
676
extern char currentwd[1024], rcfiledir[1024];
677
678
struct query *hostalloc(struct query *); 
679
int parsecmdline (int, char **, struct runctl *, struct query *);
680
char *prependdir (const char *, const char *);
681
char *MD5Digest (unsigned const char *);
682
void hmac_md5 (const unsigned char *, size_t, const unsigned char *, size_t, unsigned char *, size_t);
683
int POP3_auth_rpa(char *, char *, int socket);
684
typedef RETSIGTYPE (*SIGHANDLERTYPE) (int);
685
void deal_with_sigchld(void);
686
RETSIGTYPE null_signal_handler(int sig);
687
SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler);
688
int daemonize(const char *);
689
char *fm_getpassword(char *);
690
void escapes(const char *, char *);
691
char *visbuf(const char *);
692
const char *showproto(int);
693
void dump_config(struct runctl *runp, struct query *querylist);
694
int is_host_alias(const char *, struct query *, struct addrinfo **);
695
696
extern struct addrinfo *ai0, *ai1;
697
698
/** Try to obtain fully qualified hostname of current host. Exit with
699
 * PS_DNS if \a required is true and there is a DNS error. Exit with
700
 * PS_DNS if gethostname() fails, independent of the value of \a
701
 * required.
702
 * \return
703
 * - fully qualified hostname if \a required is non-zero.
704
 * - unqualified or fully qualified hostname if \a required is zero (0).
705
 */
706
char *host_fqdn(int required /** exit with PS_DNS if the name cannot be qualified */);
707
char *rfc822timestamp(void);
708
flag is_a_file(int);
709
char *rfc2047e(const char*, const char *);
710
711
void yyerror(const char *);
712
int yylex(void);
713
714
#ifdef __EMX__
715
void itimerthread(void*);
716
/* Have to include these first to avoid errors from redefining getcwd
717
   and chdir.  They're re-include protected in EMX, so it's okay, I
718
   guess.  */
719
#include <stdlib.h>
720
#include <unistd.h>
721
/* Redefine getcwd and chdir to get drive-letter support so we can
722
   find all of our lock files and stuff. */
723
#define getcwd _getcwd2
724
#define chdir _chdir2
725
#endif /* _EMX_ */
726
727
#ifdef HAVE_STRERROR
728
#  if !defined(strerror) && !defined(HAVE_DECL_STRERROR)	/* On some systems, strerror is a macro */
729
char *strerror (int);
730
#  endif
731
#endif /* HAVE_STRERROR */
732
733
#define STRING_DISABLED	(char *)-1
734
#define STRING_DUMMY	""
735
736
#ifdef NeXT
737
#ifndef S_IXGRP
738
#define S_IXGRP 0000010
739
#endif
740
#endif
741
742
#ifndef HAVE_STPCPY
743
char *stpcpy(char *, const char*);
744
#endif
745
746
#ifdef __CYGWIN__
747
#define ROOT_UID 18
748
#else /* !__CYGWIN__ */
749
#define ROOT_UID 0
750
#endif /* __CYGWIN__ */
751
752
extern int mailserver_socket_temp;
753
extern const char *program_name;
754
755
/* POSIX space characters,
756
 * <tab>;<newline>;<vertical-tab>;<form-feed>;<carriage-return>;<space> */
757
#define POSIX_space "\t\n\v\f\r "
758
759
/** Resolve the a TCP service name or a string containing only a decimal
760
 * positive integer to a port number. Returns -1 for error. */
761
int servport(const char *service);
762
763
#ifndef HAVE_GETNAMEINFO
764
# define NI_NUMERICHOST	1
765
# define NI_NUMERICSERV	2
766
# define NI_NOFQDN	4
767
# define NI_NAMEREQD	8
768
# define NI_DGRAM	16
769
#endif
770
771
int fm_getaddrinfo(const char *node, const char *serv, const struct addrinfo *hints, struct addrinfo **res);
772
void fm_freeaddrinfo(struct addrinfo *ai);
773
774
/* prototypes from tls.c */
775
int maybe_tls(struct query *ctl);
776
int must_tls(struct query *ctl);
777
778
/* prototype from rfc822valid.c */
779
int rfc822_valid_msgid(const unsigned char *);
780
781
/* prototype from x509_name_match.c */
782
int name_match(const char *p1, const char *p2);
783
784
/* prototype from ntlmsubr.c */
785
#ifdef NTLM_ENABLE
786
int ntlm_helper(int sock, struct query *ctl, const char *protocol);
787
#endif
788
789
/* macro to determine if we want to spam progress to stdout */
790
#define want_progress() \
791
	((outlevel >= O_VERBOSE || (outlevel > O_SILENT && run.showdots)) \
792
	&& !run.use_syslog \
793
	&& (run.showdots || !is_a_file(1)))
794
795
#endif
796
/* fetchmail.h ends here */