aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/README
blob: 5eaa51e95b8f7ad38ad2b416e49dc10d3bff1211 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
These are scripts or configuration snippets to help you running
fetchmail in special situations.

Note: you're on your own using these -- the fetchmail team undertakes no
efforts in understanding them, they are just passing them along.
								--esr, ma

This file is currently unsorted. Use your pager's search function when
looking for the description of a particular file in this directory.  --ma

### 0*.html:
Messages from the archives of the old fetchmail-friends mailing list,
for off-line reading.

### maildaemon:
Larry Fahnoe wrote this for driving fetchmail from cron.  It may be useful if
you want to force a PPP link up and then poll for mail at specified times.
I have rearranged it slightly to make it easier to configure.

### novell:

Some mail from Dan Newcombe describing how to write a procmail rule that
will domainify Novell server names.

### login & logout:

These are intended to help if you typically have multiple logins active.
Here's the script composer's original README:

	Please find attached 2 files, ~/.bash_login & ~/.bash_logout
	What these do is try to keep track of WHO is the process/tty
	that ran fetchmail in daemon mode.  I tried to use the bash
	Variable PPID, but when using xterm the PPID is set to the
	xterm's pid not the bash shell's pid so....

	They have been lightly tested.

	Any comments...

 				Hth, JimL <babydr@nwrain.net>

Doug Carter <dougc@canus.com> suggests this instead:

Add the following to your login script. (.ie .bash_profile, .profile, etc)

LOGINS=`who | grep $USER | wc -l`
if [ $LOGINS = 1 ]; then
    /usr/bin/fetchmail > /dev/null 2>&1
fi

Then add the following to your logout script. (.ie .bash_logout, etc)

LOGINS=`who | grep $USER | wc -l`
if [ $LOGINS = 1 ]; then
    /usr/bin/fetchmail -q > /dev/null 2>&1
fi

### ip-up:

A note from James Stevens about using fetchmail in an ip-up script without
disabling timeouts.

### runfetchmail:

A shellscript front end for fetchmail that mails you various statistics on
the downloaded mail and the state of your folders.  A good example of what
you can do with your own front end.

### fetchspool:

If you find that the speed of forwarding to port 25 is limited by the
SMTP listener's speed, it may make sense to locally spool all the mail
first and feed it to sendmail after you hang up the network link.
This shellscript aims to do exactly that.  It would be smarter to
figure out why sendmail is slow, however.

### fetchsetup:

This is a shell script for creating a $HOME/.fetchmailrc file, it will ask
you some questions and based on your answers it will create a .fetchmailrc
file. fetchsetup is linux specific so it may not work on another operating
system.

### mailqueue.pl:

This script will connect to your ISP (if not already connected),
send any outgoing mail and retrieve any incoming mail.  If this
program made the connection, it will also break the connection
when it is done.  By Bill Adams, <bill@evil.inetarena.com>.  The
latest version is carried at <http://evil.inetarena.com/>.

### redhat_rc:

A fetchmail boot-time init file compatible with RedHat 5.1.  It leaves
fetchmail in background to get messages when you connect to your ISP.
The invoked fetchmail expects to find its configuration in
/etc/fetchmailrc, and must include the proper "interface" directive.

### debian_rc:

A fetchmail boot-time init file compatible with Debian.  It leaves
fetchmail in background to get messages when you connect to your ISP.
The invoked fetchmail expects to find its configuration in
/root/.fetchmailrc, and must include the proper "interface" directive.

Matthias Andree adds: note that current Debian packages (as of January
2007) ship with their own init files.

### start_dynamic_ppp:

An admittedly scratchy ip-up script that Ryan Murray wrote to cope with
dynamic PPP addressing.  Will need some customizing.

	http://www.inetarena.com/~badams/linux/programs/mailqueue.pl

### getfetchmail:

Here's a script that gets Eric's most recent fetchmail source rpm,
downloads it and (if the rpm's not broken) rebuilds it.

With fairly simple changes it can be used to download the latest i386 rpm
or tar.gz.

Those who are addicted to having the latest of everything could filter mail
from fetchmail announce through it and get new versions as they're
announced. However, if we all did that, Eric's ftp server might feel a
little stressed.

The script as written works on bash 2.  By John Summerfield
<summer@os2.ami.com.au>.

### zsh-completion:

These commands set up command completion for fetchmail under zsh.
Jay Kominek <jay.kominek@colorado.edu>.

### getmail/gotmail:

These scripts are front ends for fetchmail in daemon mode that can gather
log statistics and generate text or HTML reports.  See README.getmail for
details.  Scripts by Thomas Nesges <ThomaNesges@TNT-Computer.de>.

### fetchmaildistrib:

This script resolves the issue where the sysadmin polls for mail with fetchmail
only at set intervals, but where a user wishes to see his email right
away. The duplication in /etc/fetchmailrc and ~/.fetchmailrc files is
automated with this script; whenever /etc/fetchmailrc is changed, this
script is run to distribute the stuff into all user's ~/.fetchmailrc
files.

### multidrop:

Martijn Lievaart's sendmail hacks to make multidrop reliable.

### domino:

Gustavo Chaves <gustavo@cpqd.com.br> wrote this script to deal with 
the boundary-mismatch bug in Domino (see FAQ item X5).  If you use
this with --mda, the broken boundaries will be fixed and the result
passed to procmail.

### toprocmail:

John Lim Eng Hooi <jleh@mail.com> wrote this script, yet another 
mda plugin, to be used with fetchmail in foreground mode.  It displays
some header lines to stdout in color, passing them (and the rest of the
message content) to procmail.

### preauth-harness:

Emmanuel Dreyfus's Perl test script for exercising IMAP PREAUTH
connections.  You'll have to patch in your username and password.

### sm-hybrid:

Peter 'Rattacresh' Backes sent this patch to improve the behavior of 
sendmail 8.11.0 with multidrop.

### fetchmailnochda.pl

Watchdog script to check whether fetchmail is working in daemon mode.

### mold-remover.py

A short python script to remove old read mail from a pop3 mailserver.
Dovetails with fetchmail with keep option.  Run it as a cron job.

### PopDel.py

PopDel stands for Pop Delete; this program deletes selected email from a
pop mail server. (By Richard Harris, improved by Joshua Crawford.)

### fetchmail.logrotate (added 2007-01-14, --ma)

A logrotate configuration file developped by Daniel Leidert for Debian,
when he wanted to use /var/log/fetchmail instead of the usual syslog.
It probably needs to be adjusted for use on other systems.

### delete-later (added 2007-03-17, --ma)

A MySQL/Tcl/Expect-based client-side script to remove messages at a
certain age.  See delete-later.README for details.
(By Carsten Ralle, Yoo GmbH, Germany.)

### gai (added 2013-02-03, --ma)

A trivial getaddrinfo() program to check the getaddrinfo() call from the
system, as a research tool for the fetchmail developers.
n class="cpf"><string.h> #if defined(HAVE_SYSLOG) #include <syslog.h> #endif #include "i18n.h" #include "fetchmail.h" #if defined(HAVE_VPRINTF) || defined(HAVE_DOPRNT) || defined(_LIBC) || defined(HAVE_STDARG_H) # if HAVE_STDARG_H # include <stdarg.h> # define VA_START(args, lastarg) va_start(args, lastarg) # else # include <varargs.h> # define VA_START(args, lastarg) va_start(args) # endif #else # define va_alist a1, a2, a3, a4, a5, a6, a7, a8 # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; #endif #define MALLOC(n) xmalloc(n) #define REALLOC(n,s) xrealloc(n,s) /* Used by report_build() and report_complete() to accumulate partial messages. */ static unsigned int partial_message_size = 0; static unsigned int partial_message_size_used = 0; static char *partial_message; static int partial_suppress_tag = 0; static unsigned unbuffered; static unsigned int use_syslog; #ifdef _LIBC /* In the GNU C library, there is a predefined variable for this. */ # define program_name program_invocation_name # include <errno.h> #else # if !HAVE_STRERROR && !defined(strerror) char *strerror (int errnum) { extern char *sys_errlist[]; extern int sys_nerr; if (errnum > 0 && errnum <= sys_nerr) return sys_errlist[errnum]; return GT_("Unknown system error"); } # endif /* HAVE_STRERROR */ #endif /* _LIBC */ /* Print the program name and error message MESSAGE, which is a printf-style format string with optional args. */ /* VARARGS */ void #ifdef HAVE_STDARG_H report (FILE *errfp, const char *message, ...) #else report (FILE *errfp, message, va_alist) const char *message; va_dcl #endif { #ifdef VA_START va_list args; #endif /* If a partially built message exists, print it now so it's not lost. */ if (partial_message_size_used != 0) { partial_message_size_used = 0; report (errfp, GT_("%s (log message incomplete)\n"), partial_message); } #if defined(HAVE_SYSLOG) if (use_syslog) { int priority; #ifdef VA_START VA_START (args, message); #endif priority = (errfp == stderr) ? LOG_ERR : LOG_INFO; #ifdef HAVE_VSYSLOG vsyslog (priority, message, args); #else { char *a1 = va_arg(args, char *); char *a2 = va_arg(args, char *); char *a3 = va_arg(args, char *); char *a4 = va_arg(args, char *); char *a5 = va_arg(args, char *); char *a6 = va_arg(args, char *); char *a7 = va_arg(args, char *); char *a8 = va_arg(args, char *); syslog (priority, message, a1, a2, a3, a4, a5, a6, a7, a8); } #endif #ifdef VA_START va_end(args); #endif } else /* i. e. not using syslog */ #endif { if ( *message == '\n' ) { fputc( '\n', errfp ); ++message; } if (!partial_suppress_tag) fprintf (errfp, "%s: ", program_name); partial_suppress_tag = 0; #ifdef VA_START VA_START (args, message); # if defined(HAVE_VPRINTF) || defined(_LIBC) vfprintf (errfp, message, args); # else _doprnt (message, args, errfp); # endif va_end (args); #else fprintf (errfp, message, a1, a2, a3, a4, a5, a6, a7, a8); #endif fflush (errfp); } } /** * Configure the report module. The output is set according to * \a mode. */ void report_init(int mode /** 0: regular output, 1: unbuffered output, -1: syslog */) { switch(mode) { case 0: /* errfp, buffered */ default: unbuffered = FALSE; use_syslog = FALSE; break; case 1: /* errfp, unbuffered */ unbuffered = TRUE; use_syslog = FALSE; break; #ifdef HAVE_SYSLOG case -1: /* syslogd */ unbuffered = FALSE; use_syslog = TRUE; break; #endif /* HAVE_SYSLOG */ } } /* Build an report message by appending MESSAGE, which is a printf-style format string with optional args, to the existing report message (which may be empty.) The completed report message is finally printed (and reset to empty) by calling report_complete(). If an intervening call to report() occurs when a partially constructed message exists, then, in an attempt to keep the messages in their proper sequence, the partial message will be printed as-is (with a trailing newline) before report() prints its message. */ /* VARARGS */ static void rep_ensuresize(void) { /* Make an initial guess for the size of any single message fragment. */ if (partial_message_size == 0) { partial_message_size_used = 0; partial_message_size = 2048; partial_message = (char *)MALLOC (partial_message_size); } else if (partial_message_size - partial_message_size_used < 1024) { partial_message_size += 2048; partial_message = (char *)REALLOC (partial_message, partial_message_size); } } #ifdef HAVE_STDARG_H static void report_vbuild(const char *message, va_list args) { int n; for ( ; ; ) { /* * args has to be initialized before every call of vsnprintf(), * because vsnprintf() invokes va_arg macro and thus args is * undefined after the call. */ n = vsnprintf (partial_message + partial_message_size_used, partial_message_size - partial_message_size_used, message, args); /* output error, f. i. EILSEQ */ if (n < 0) break; if (n >= 0 && (unsigned)n < partial_message_size - partial_message_size_used) { partial_message_size_used += n; break; } partial_message_size += 2048; partial_message = (char *)REALLOC (partial_message, partial_message_size); } } #endif void #ifdef HAVE_STDARG_H report_build (FILE *errfp, const char *message, ...) #else report_build (FILE *errfp, message, va_alist) const char *message; va_dcl #endif { #ifdef VA_START va_list args; #else int n; #endif rep_ensuresize(); #if defined(VA_START) VA_START(args, message); report_vbuild(message, args); va_end(args); #else for ( ; ; ) { n = snprintf (partial_message + partial_message_size_used, partial_message_size - partial_message_size_used, message, a1, a2, a3, a4, a5, a6, a7, a8); /* output error, f. i. EILSEQ */ if (n < 0) break; if (n >= 0 && (unsigned)n < partial_message_size - partial_message_size_used) { partial_message_size_used += n; break; } partial_message_size += 2048; partial_message = REALLOC (partial_message, partial_message_size); } #endif if (unbuffered && partial_message_size_used != 0) { partial_message_size_used = 0; fputs(partial_message, errfp); } } void report_flush(FILE *errfp) { if (partial_message_size_used != 0) { partial_message_size_used = 0; report(errfp, "%s", partial_message); partial_suppress_tag = 1; } } /* Complete a report message by appending MESSAGE, which is a printf-style format string with optional args, to the existing report message (which may be empty.) The completed report message is then printed (and reset to empty.) */ /* VARARGS */ void #ifdef HAVE_STDARG_H report_complete (FILE *errfp, const char *message, ...) #else report_complete (FILE *errfp, message, va_alist) const char *message; va_dcl #endif { #ifdef VA_START va_list args; #endif rep_ensuresize(); #if defined(VA_START) VA_START(args, message); report_vbuild(message, args); va_end(args); #else report_build(errfp, message, a1, a2, a3, a4, a5, a6, a7, a8); #endif /* Finally... print it. */ partial_message_size_used = 0; if (unbuffered) { fputs(partial_message, errfp); fflush (errfp); } else report(errfp, "%s", partial_message); } /* Sometimes we want to have at most one error per line. This variable controls whether this mode is selected or not. */ static int error_one_per_line; /* If errnum is nonzero, print its corresponding system error message. */ void #ifdef HAVE_STDARG_H report_at_line (FILE *errfp, int errnum, const char *file_name, unsigned int line_number, const char *message, ...) #else report_at_line (FILE *errfp, errnum, file_name, line_number, message, va_alist) int errnum; const char *file_name; unsigned int line_number; const char *message; va_dcl #endif { #ifdef VA_START va_list args; #endif if (error_one_per_line) { static const char *old_file_name; static unsigned int old_line_number; if (old_line_number == line_number && (file_name == old_file_name || (old_file_name != NULL && 0 == strcmp (old_file_name, file_name)))) /* Simply return and print nothing. */ return; old_file_name = file_name; old_line_number = line_number; } fflush (errfp); if ( *message == '\n' ) { fputc( '\n', errfp ); ++message; } fprintf (errfp, "%s:", program_name); if (file_name != NULL) fprintf (errfp, "%s:%u: ", file_name, line_number); #ifdef VA_START VA_START (args, message); # if defined(HAVE_VPRINTF) || defined(_LIBC) vfprintf (errfp, message, args); # else _doprnt (message, args, errfp); # endif va_end (args); #else fprintf (errfp, message, a1, a2, a3, a4, a5, a6, a7, a8); #endif if (errnum) fprintf (errfp, ": %s", strerror (errnum)); putc ('\n', errfp); fflush (errfp); }