aboutsummaryrefslogtreecommitdiffstats
path: root/driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver.c')
-rw-r--r--driver.c113
1 files changed, 90 insertions, 23 deletions
diff --git a/driver.c b/driver.c
index 6d09ff51..6016de51 100644
--- a/driver.c
+++ b/driver.c
@@ -819,7 +819,7 @@ static int readheaders(int sock, long fetchlen, long reallen, struct query *ctl,
}
else
{
- /* set up sinkfp so we can deliver the message body through it */
+ /* set up stuffline() so we can deliver the message body through it */
if ((n = open_sink(ctl, return_path, xmit_names, reallen,
&good_addresses, &bad_addresses)) != PS_SUCCESS)
{
@@ -1229,15 +1229,71 @@ static void clean_skipped_list(struct idlist **skipped_list)
*skipped_list = head;
}
-static void send_warning(struct query *ctl)
+static open_warning_by_mail(struct query *ctl)
+/* set up output sink for a mailed warning to calling user */
+{
+ int good, bad;
+
+ /*
+ * We give a null address list as arg 3 because we actually *want*
+ * this message to go to run.postmaster. The zero length arg 4 means
+ * we won't pass a SIZE option to ESMTP; the message length would
+ * be more trouble than it's worth to compute.
+ */
+ return(open_sink(ctl, "FETCHMAIL-DAEMON", NULL, 0, &good, &bad));
+}
+
+#if defined(HAVE_STDARG_H)
+void stuff_warning_line(struct query *ctl, const char *fmt, ... )
+#else
+void stuff_warning_line(struct query *ctl, fmt, va_alist)
+struct query *ctl;
+const char *fmt; /* printf-style format */
+va_dcl
+#endif
+/* format and ship a warning message line by mail */
+{
+ char buf[POPBUFSIZE];
+ va_list ap;
+
+ /*
+ * stuffline() requires its input to be writeable (for CR stripping),
+ * so we needed to copy the message to a writeable buffer anyway in
+ * case it was a string constant. We make a virtue of that necessity
+ * here by supporting stdargs/varargs.
+ */
+#if defined(HAVE_STDARG_H)
+ va_start(ap, fmt) ;
+#else
+ va_start(ap);
+#endif
+#ifdef HAVE_VSNPRINTF
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+#else
+ vsprintf(buf, fmt, ap);
+#endif
+ va_end(ap);
+
+ strcat(buf, "\r\n");
+
+ stuffline(ctl, buf);
+}
+
+static close_warning_by_mail(struct query *ctl)
+/* sign and send mailed warnings */
+{
+ stuff_warning_line(ctl, "--\r\n\t\t\t\tThe Fetchmail Daemon\r\n");
+ close_sink(ctl, TRUE);
+}
+
+static void send_size_warnings(struct query *ctl)
/* send warning mail with skipped msg; reset msg count when user notified */
{
int size, nbr;
int msg_to_send = FALSE;
struct idlist *head=NULL, *current=NULL;
int max_warning_poll_count, good, bad;
-#define OVERHD "Subject: Fetchmail WARNING.\r\n\r\nThe following oversized messages remain on the mail server:\n\r\n"
- char buf[sizeof(OVERHD) + 2];
+#define OVERHD "Subject: Fetchmail oversized-messages warning.\r\n\r\nThe following oversized messages remain on the mail server:"
head = ctl->skipped;
if (!head)
@@ -1254,18 +1310,10 @@ static void send_warning(struct query *ctl)
* There's no good way to recover if we can't send notification mail,
* but it's not a disaster, either, since the skipped mail will not
* be deleted.
- *
- * We give a null address list as arg 3 because we actually *want*
- * this message to go to run.postmaster. The zero length arg 4 means
- * we won't pass a SIZE option to ESMTP; the message length would
- * be more trouble than it's worth to compute.
*/
- if (open_sink(ctl, "FETCHMAIL-DAEMON", NULL, 0, &good, &bad))
+ if (open_warning_by_mail(ctl))
return;
-
- /* stuffline() requires its input to be writeable for CR stripping */
- strcpy(buf, OVERHD);
- stuffline(ctl, buf);
+ stuff_warning_line(ctl, OVERHD);
if (run.poll_interval == 0)
max_warning_poll_count = 0;
@@ -1279,10 +1327,9 @@ static void send_warning(struct query *ctl)
{
nbr = current->val.status.mark;
size = atoi(current->id);
- sprintf(buf,
- "\t%d msg %d octets long skipped by fetchmail.\n",
+ stuff_warning_line(ctl,
+ "\t%d msg %d octets long skipped by fetchmail.",
nbr, size);
- stuffline(ctl, buf);
}
current->val.status.num++;
current->val.status.mark = 0;
@@ -1291,7 +1338,7 @@ static void send_warning(struct query *ctl)
current->val.status.num = 0;
}
- close_sink(ctl, TRUE);
+ close_warning_by_mail(ctl);
#undef OVERHD
}
@@ -1510,6 +1557,28 @@ const struct method *proto; /* protocol method table */
error(0, -1, "Authorization failure on %s@%s",
ctl->remotename,
ctl->server.truename);
+
+ /*
+ * If we're running in background, try to mail the
+ * calling user a heads-up about the authentication
+ * failure the first time it happens.
+ */
+ if (run.poll_interval && !nodetach
+ && !ctl->authfailcount && !open_warning_by_mail(ctl))
+ {
+ stuff_warning_line(ctl,
+ "Subject: fetchmail authentication failed\r\n");
+ stuff_warning_line(ctl,
+ "Fetchmail could not get mail from %s@%s.",
+ ctl->remotename,
+ ctl->server.truename);
+ stuff_warning_line(ctl,
+ "The attempt to get authorization failed.");
+ stuff_warning_line(ctl,
+ "This probably means your password is invalid.");
+ close_warning_by_mail(ctl);
+ ctl->authfailcount++;
+ }
}
goto cleanUp;
}
@@ -1925,7 +1994,7 @@ const struct method *proto; /* protocol method table */
if (!check_only && ctl->skipped)
{
clean_skipped_list(&ctl->skipped);
- send_warning(ctl);
+ send_size_warnings(ctl);
}
}
} while
@@ -2011,14 +2080,13 @@ closeUp:
#if defined(HAVE_STDARG_H)
void gen_send(int sock, const char *fmt, ... )
-/* assemble command in printf(3) style and send to the server */
#else
void gen_send(sock, fmt, va_alist)
-/* assemble command in printf(3) style and send to the server */
int sock; /* socket to which server is connected */
const char *fmt; /* printf-style format */
va_dcl
#endif
+/* assemble command in printf(3) style and send to the server */
{
char buf [MSGBUFSIZE+1];
va_list ap;
@@ -2094,14 +2162,13 @@ int size; /* length of buffer */
#if defined(HAVE_STDARG_H)
int gen_transact(int sock, const char *fmt, ... )
-/* assemble command in printf(3) style, send to server, accept a response */
#else
int gen_transact(int sock, fmt, va_alist)
-/* assemble command in printf(3) style, send to server, accept a response */
int sock; /* socket to which server is connected */
const char *fmt; /* printf-style format */
va_dcl
#endif
+/* assemble command in printf(3) style, send to server, accept a response */
{
int ok;
char buf [MSGBUFSIZE+1];