2 * driver.c -- generic driver for mail fetch method protocols
4 * Copyright 1996 by Eric S. Raymond
6 * For license terms, see the file COPYING in this directory.
14 #if defined(STDC_HEADERS)
17 #if defined(HAVE_UNISTD_H)
20 #if defined(HAVE_STDARG_H)
25 #if defined(HAVE_ALLOCA_H)
31 #ifdef HAVE_GETHOSTBYNAME
34 #endif /* HAVE_GETHOSTBYNAME */
39 #include <netinet/in.h> /* must be included before "socket.h".*/
41 #endif /* KERBEROS_V4 */
43 #include "fetchmail.h"
46 /* BSD portability hack...I know, this is an ugly place to put it */
47 #if !defined(SIGCLD) && defined(SIGCHLD)
48 #define SIGCLD SIGCHLD
51 #define SMTP_PORT 25 /* standard SMTP service port */
53 int batchlimit; /* how often to tear down the delivery connection */
54 int batchcount; /* count of messages sent in current batch */
55 int peek_capable; /* can we peek for better error recovery? */
57 static const struct method *protocol;
58 static jmp_buf restart;
62 #define GENSYM (sprintf(tag, "a%04d", ++tagnum), tag)
64 static char *shroud; /* string to shroud in debug output, if non-NULL */
65 static int mytimeout; /* value of nonreponse timeout */
67 static int strcrlf(dst, src, count)
68 /* replace LFs with CR-LF; return length of string with replacements */
69 char *dst; /* new string with CR-LFs */
70 char *src; /* original string with LFs */
71 int count; /* length of src */
88 static void vtalarm(int timeleft)
89 /* reset the nonresponse-timeout */
91 struct itimerval ntimeout;
93 ntimeout.it_interval.tv_sec = ntimeout.it_interval.tv_usec = 0;
94 ntimeout.it_value.tv_sec = timeleft;
95 ntimeout.it_value.tv_usec = 0;
96 setitimer(ITIMER_VIRTUAL, &ntimeout, (struct itimerval *)NULL);
99 static void vtalarm_handler (int signal)
100 /* handle server-timeout SIGVTALARM signal */
105 #ifdef HAVE_RES_SEARCH
108 static int is_host_alias(const char *name, struct query *ctl)
109 /* determine whether name is a DNS alias of the hostname */
112 struct mxentry *mxp, *mxrecords;
115 * The first two checks are optimizations that will catch a good
116 * many cases. (1) check against the hostname the user
117 * specified. Odds are good this will either be the mailserver's
118 * FQDN or a suffix of it with the mailserver's domain's default
119 * host name omitted. Then check the rest of the `also known as'
120 * cache accumulated by previous DNS checks. This cache is primed
121 * by the aka list option.
123 * (2) check against the mailserver's FQDN, in case
124 * it's not the same as the declared hostname.
126 * Either of these on a mail address is definitive. Only if the
127 * name doesn't match either is it time to call the bind library.
128 * If this happens odds are good we're looking at an MX name.
130 if (str_in_list(&ctl->lead_server->servernames, name))
132 else if (strcmp(name, ctl->canonical_name) == 0)
136 * We know DNS service was up at the beginning of this poll cycle.
137 * If it's down, our nameserver has crashed. We don't want to try
138 * delivering the current message or anything else from this
139 * mailbox until it's back up.
141 else if ((he = gethostbyname(name)) != (struct hostent *)NULL)
143 if (strcmp(ctl->canonical_name, he->h_name) == 0)
151 case HOST_NOT_FOUND: /* specified host is unknown */
152 case NO_ADDRESS: /* valid, but does not have an IP address */
155 case NO_RECOVERY: /* non-recoverable name server error */
156 case TRY_AGAIN: /* temporary error on authoritative server */
158 if (outlevel != O_SILENT)
159 putchar('\n'); /* terminate the progress message */
161 "fetchmail: nameserver failure while looking for `%s' during poll of %s.\n",
162 name, ctl->servernames->id);
164 longjmp(restart, 2); /* try again next poll cycle */
169 * We're only here if DNS was OK but the gethostbyname() failed
170 * with a HOST_NOT_FOUND or NO_ADDRESS error.
171 * Search for a name match on MX records pointing to the server.
174 if ((mxrecords = getmxrecords(name)) == (struct mxentry *)NULL)
178 case HOST_NOT_FOUND: /* specified host is unknown */
181 case NO_ADDRESS: /* valid, but does not have an IP address */
182 for (mxp = mxrecords; mxp->name; mxp++)
183 if (strcmp(name, mxp->name) == 0)
188 case NO_RECOVERY: /* non-recoverable name server error */
189 case TRY_AGAIN: /* temporary error on authoritative server */
192 "fetchmail: nameserver failure while looking for `%s' during poll of %s.\n",
193 name, ctl->servernames->id);
195 longjmp(restart, 2); /* try again next poll cycle */
201 /* add this name to relevant server's `also known as' list */
202 save_str(&ctl->lead_server->servernames, -1, name);
206 static void map_name(name, ctl, xmit_names)
207 /* add given name to xmit_names if it matches declared localnames */
208 const char *name; /* name to map */
209 struct query *ctl; /* list of permissible aliases */
210 struct idlist **xmit_names; /* list of recipient names parsed out */
214 lname = idpair_find(&ctl->localnames, name);
215 if (!lname && ctl->wildcard)
218 if (lname != (char *)NULL)
220 if (outlevel == O_VERBOSE)
222 "fetchmail: mapped %s to local %s\n",
224 save_str(xmit_names, -1, lname);
228 void find_server_names(hdr, ctl, xmit_names)
229 /* parse names out of a RFC822 header into an ID list */
230 const char *hdr; /* RFC822 header in question */
231 struct query *ctl; /* list of permissible aliases */
232 struct idlist **xmit_names; /* list of recipient names parsed out */
234 if (hdr == (char *)NULL)
240 if ((cp = nxtaddr(hdr)) != (char *)NULL)
244 if ((atsign = strchr(cp, '@')))
247 * Address has an @. Check to see if the right-hand part
248 * is an alias or MX equivalent of the mailserver. If it's
249 * not, skip this name. If it is, we'll keep going and try
250 * to find a mapping to a client name.
252 if (!is_host_alias(atsign+1, ctl))
257 map_name(cp, ctl, xmit_names);
259 ((cp = nxtaddr((char *)NULL)) != (char *)NULL);
262 #endif /* HAVE_RES_SEARCH */
264 static FILE *smtp_open(struct query *ctl)
265 /* try to open a socket to the appropriate SMTP server for this query */
267 ctl = ctl->lead_smtp; /* go to the SMTP leader for this query */
269 /* maybe it's time to close the socket in order to force delivery */
270 if (batchlimit && ctl->smtp_sockfp && batchcount++ == batchlimit)
272 fclose(ctl->smtp_sockfp);
273 ctl->smtp_sockfp = (FILE *)NULL;
277 /* if no socket to this host is already set up, try to open one */
278 if (ctl->smtp_sockfp == (FILE *)NULL)
280 if ((ctl->smtp_sockfp = Socket(ctl->smtphost, SMTP_PORT)) == (FILE *)NULL)
281 return((FILE *)NULL);
282 else if (SMTP_ok(ctl->smtp_sockfp) != SM_OK
283 || SMTP_helo(ctl->smtp_sockfp, ctl->servernames->id) != SM_OK)
285 fclose(ctl->smtp_sockfp);
286 ctl->smtp_sockfp = (FILE *)NULL;
290 return(ctl->smtp_sockfp);
293 static int gen_readmsg (sockfp, len, delimited, ctl)
294 /* read message content and ship to SMTP or MDA */
295 FILE *sockfp; /* to which the server is connected */
296 long len; /* length of message */
297 int delimited; /* does the protocol use a message delimiter? */
298 struct query *ctl; /* query control record */
300 char buf [MSGBUFSIZE+1];
301 char *bufp, *headers, *fromhdr,*tohdr,*cchdr,*bcchdr,*received_for,*envto;
302 int n, oldlen, mboxfd;
303 int inheaders,lines,sizeticker;
305 RETSIGTYPE (*sigchld)();
306 #ifdef HAVE_GETHOSTBYNAME
307 char rbuf[HOSTLEN + USERNAMELEN + 4];
308 #endif /* HAVE_GETHOSTBYNAME */
310 /* read the message content from the server */
312 headers = fromhdr = tohdr = cchdr = bcchdr = received_for = envto = NULL;
316 while (delimited || len > 0)
318 if ((n = SockGets(buf,sizeof(buf),sockfp)) < 0)
320 vtalarm(ctl->timeout);
322 /* write the message size dots */
326 while (sizeticker >= SIZETICKER)
328 if (outlevel > O_SILENT)
330 sizeticker -= SIZETICKER;
335 if (buf[0] == '\0' || buf[0] == '\r' || buf[0] == '\n')
337 if (delimited && *bufp == '.') {
340 break; /* end of message */
347 reply_hack(bufp, ctl->servernames->id);
351 oldlen = strlen(bufp);
352 headers = xmalloc(oldlen + 1);
353 (void) strcpy(headers, bufp);
361 * We deal with RFC822 continuation lines here.
362 * Replace previous '\n' with '\r' so nxtaddr
363 * and reply_hack will be able to see past it.
364 * (We know this is safe because SocketGets stripped
365 * out all carriage returns in the read loop above
366 * and we haven't reintroduced any since then.)
367 * We'll undo this before writing the header.
369 if (isspace(bufp[0]))
370 headers[oldlen-1] = '\r';
372 newlen = oldlen + strlen(bufp);
373 headers = realloc(headers, newlen + 1);
376 strcpy(headers + oldlen, bufp);
377 bufp = headers + oldlen;
381 if (!strncasecmp("From:", bufp, 5))
383 else if (!fromhdr && !strncasecmp("Resent-From:", bufp, 12))
385 else if (!fromhdr && !strncasecmp("Apparently-From:", bufp, 16))
387 else if (!strncasecmp("To:", bufp, 3))
389 else if (!strncasecmp("Apparently-To:", bufp, 14))
391 else if (!strncasecmp(ctl->envelope, bufp, 14))
393 else if (!strncasecmp("Cc:", bufp, 3))
395 else if (!strncasecmp("Bcc:", bufp, 4))
397 #ifdef HAVE_GETHOSTBYNAME
398 else if (MULTIDROP(ctl) && !strncasecmp("Received:", bufp, 9))
403 * Try to extract the real envelope addressee. We look here
404 * specifically for the mailserver's Received line.
405 * Note: this will only work for sendmail, or an MTA that
406 * shares sendmail's convention of embedding the envelope
407 * address in the Received line.
410 strcat(rbuf, ctl->canonical_name);
411 if ((ok = strstr(bufp, rbuf)))
412 ok = strstr(ok, "for <");
423 while (*sp && *sp != '>' && *sp != '@' && *sp != ';')
428 /* uh oh -- whitespace here can't be right! */
437 received_for = alloca(strlen(rbuf)+1);
438 strcpy(received_for, rbuf);
439 if (outlevel == O_VERBOSE)
441 "fetchmail: found Received address `%s'\n",
445 #endif /* HAVE_GETHOSTBYNAME */
449 else if (headers) /* OK, we're at end of headers now */
452 struct idlist *idp, *xmit_names;
453 int good_addresses, bad_addresses;
454 #ifdef HAVE_RES_SEARCH
455 int no_local_matches = FALSE;
456 #endif /* HAVE_RES_SEARCH */
458 /* cons up a list of local recipients */
459 xmit_names = (struct idlist *)NULL;
460 bad_addresses = good_addresses = 0;
461 #ifdef HAVE_RES_SEARCH
462 /* is this a multidrop box? */
465 if (envto) /* We have the actual envelope addressee */
466 find_server_names(envto, ctl, &xmit_names);
467 else if (received_for)
469 * We have the Received for addressee.
470 * It has to be a mailserver address, or we
471 * wouldn't have got here.
473 map_name(received_for, ctl, &xmit_names);
477 * We haven't extracted the envelope address.
478 * So check all the header addresses.
480 find_server_names(tohdr, ctl, &xmit_names);
481 find_server_names(cchdr, ctl, &xmit_names);
482 find_server_names(bcchdr, ctl, &xmit_names);
486 no_local_matches = TRUE;
487 save_str(&xmit_names, -1, user);
488 if (outlevel == O_VERBOSE)
490 "fetchmail: no local matches, forwarding to %s\n",
494 else /* it's a single-drop box, use first localname */
495 #endif /* HAVE_RES_SEARCH */
496 save_str(&xmit_names, -1, ctl->localnames->id);
498 /* time to address the message */
499 if (ctl->mda[0]) /* we have a declared MDA */
505 * We go through this in order to be able to handle very
506 * long lists of users and (re)implement %s.
508 for (idp = xmit_names; idp; idp = idp->next)
510 sp = sargv = (char **)alloca(sizeof(char **) * ctl->mda_argcount+nlocals+2);
511 for (i = 0; i < ctl->mda_argcount; i++)
512 if (strcmp("%s", ctl->mda_argv[i]))
513 *sp++ = ctl->mda_argv[i];
515 for (idp = xmit_names; idp; idp = idp->next)
521 * Arrange to run with user's permissions if we're root.
522 * This will initialize the ownership of any files the
523 * MDA creates properly. (The seteuid call is available
524 * under all BSDs and Linux)
527 #endif /* HAVE_SETEUID */
529 mboxfd = openmailpipe(sargv);
532 /* this will fail quietly if we didn't start as root */
534 #endif /* HAVE_SETEUID */
538 fprintf(stderr, "fetchmail: MDA open failed\n");
542 sigchld = signal(SIGCLD, SIG_DFL);
548 /* build a connection to the SMTP listener */
549 if (ctl->mda[0] == '\0' && ((sinkfp = smtp_open(ctl)) == NULL))
551 free_str_list(&xmit_names);
552 fprintf(stderr, "fetchmail: SMTP connect failed\n");
557 * Try to get the SMTP listener to take the header
558 * From address as MAIL FROM (this makes the logging
559 * nicer). If it won't, fall back on the calling-user
560 * ID. This won't affect replies, which use the header
561 * From address anyway.
563 if (!fromhdr || !(ap = nxtaddr(fromhdr)))
565 if (SMTP_from(sinkfp, user) != SM_OK)
566 return(PS_SMTP); /* should never happen */
568 else if (SMTP_from(sinkfp, ap) != SM_OK)
569 if (smtp_response == 571)
572 * SMTP listener explicitly refuses to deliver
573 * mail coming from this address, probably due
574 * to an anti-spam domain exclusion. Respect
577 sinkfp = (FILE *)NULL;
580 else if (SMTP_from(sinkfp, user) != SM_OK)
581 return(PS_SMTP); /* should never happen */
583 /* now list the recipient addressees */
584 for (idp = xmit_names; idp; idp = idp->next)
585 if (SMTP_rcpt(sinkfp, idp->id) == SM_OK)
592 "fetchmail: SMTP listener doesn't like recipient address `%s'\n", idp->id);
594 if (!good_addresses && SMTP_rcpt(sinkfp, user) != SM_OK)
597 "fetchmail: can't even send to calling user!\n");
601 /* tell it we're ready to send data */
603 if (outlevel == O_VERBOSE)
604 fputs("SMTP> ", stderr);
609 /* change continuation markers back to regular newlines */
610 for (cp = headers; cp < headers + oldlen; cp++)
614 /* replace all LFs with CR-LF before sending to the SMTP server */
617 char *newheaders = xmalloc(1 + oldlen * 2);
619 oldlen = strcrlf(newheaders, headers, oldlen);
621 headers = newheaders;
624 /* write all the headers */
626 n = write(mboxfd,headers,oldlen);
628 n = SockWrite(headers, oldlen, sinkfp);
634 perror("fetchmail: writing RFC822 headers");
637 closemailpipe(mboxfd);
638 signal(SIGCLD, sigchld);
642 else if (outlevel == O_VERBOSE)
647 /* write error notifications */
648 #ifdef HAVE_RES_SEARCH
649 if (no_local_matches || bad_addresses)
652 #endif /* HAVE_RES_SEARCH */
655 char errhd[USERNAMELEN + POPBUFSIZE], *errmsg;
658 (void) strcpy(errhd, "X-Fetchmail-Warning: ");
659 #ifdef HAVE_RES_SEARCH
660 if (no_local_matches)
662 strcat(errhd, "no recipient addresses matched declared local names");
666 #endif /* HAVE_RES_SEARCH */
670 strcat(errhd, "SMTP listener rejected local recipient addresses: ");
671 errlen = strlen(errhd);
672 for (idp = xmit_names; idp; idp = idp->next)
674 errlen += strlen(idp->id) + 2;
676 errmsg = alloca(errlen+3);
677 (void) strcpy(errmsg, errhd);
678 for (idp = xmit_names; idp; idp = idp->next)
681 strcat(errmsg, idp->id);
683 strcat(errmsg, ", ");
687 strcat(errmsg, "\n");
690 write(mboxfd, errmsg, strlen(errmsg));
692 SockWrite(errmsg, strlen(errmsg), sinkfp);
695 free_str_list(&xmit_names);
698 /* SMTP byte-stuffing */
699 if (*bufp == '.' && ctl->mda[0] == 0)
701 SockWrite(".", 1, sinkfp);
703 /* replace all LFs with CR-LF in the line */
706 char *newbufp = xmalloc(1 + strlen(bufp) * 2);
708 strcrlf(newbufp, bufp, strlen(bufp));
712 /* ship out the text line */
714 n = write(mboxfd,bufp,strlen(bufp));
716 n = SockWrite(bufp, strlen(bufp), sinkfp);
722 perror("fetchmail: writing message text");
725 closemailpipe(mboxfd);
726 signal(SIGCLD, sigchld);
730 else if (outlevel == O_VERBOSE)
741 /* close the delivery pipe, we'll reopen before next message */
742 rc = closemailpipe(mboxfd);
743 signal(SIGCLD, sigchld);
749 /* write message terminator */
750 if (SMTP_eom(sinkfp) != SM_OK)
752 fputs("fetchmail: SMTP listener refused delivery\n", stderr);
762 kerberos_auth (socket, canonical)
763 /* authenticate to the server host using Kerberos V4 */
764 int socket; /* socket to server host */
765 const char *canonical; /* server name */
771 Key_schedule schedule;
774 ticket = ((KTEXT) (malloc (sizeof (KTEXT_ST))));
775 rem = (krb_sendauth (0L, socket, ticket, "pop",
777 ((char *) (krb_realmofhost (canonical))),
782 ((struct sockaddr_in *) 0),
783 ((struct sockaddr_in *) 0),
788 fprintf (stderr, "fetchmail: kerberos error %s\n", (krb_get_err_text (rem)));
793 #endif /* KERBEROS_V4 */
795 int do_protocol(ctl, proto)
796 /* retrieve messages from server using given protocol method table */
797 struct query *ctl; /* parsed options with merged-in defaults */
798 const struct method *proto; /* protocol method table */
804 if (ctl->authenticate == A_KERBEROS)
806 fputs("fetchmail: Kerberos support not linked.\n", stderr);
809 #endif /* KERBEROS_V4 */
811 /* lacking methods, there are some options that may fail */
814 /* check for unsupported options */
817 "Option --flush is not supported with %s\n",
821 else if (ctl->fetchall) {
823 "Option --all is not supported with %s\n",
828 if (!proto->getsizes && ctl->limit)
831 "Option --limit is not supported with %s\n",
838 tag[0] = '\0'; /* nuke any tag hanging out from previous query */
841 /* set up the server-nonresponse timeout */
842 sigsave = signal(SIGVTALRM, vtalarm_handler);
843 vtalarm(mytimeout = ctl->timeout);
845 if ((js = setjmp(restart)) == 1)
848 "fetchmail: timeout after %d seconds waiting for %s.\n",
849 ctl->timeout, ctl->servernames->id);
854 /* error message printed at point of longjmp */
859 char buf [POPBUFSIZE+1];
860 int *msgsizes, len, num, count, new, deletions = 0;
863 /* open a socket to the mail server */
864 if ((sockfp = Socket(ctl->servernames->id,
865 ctl->port ? ctl->port : protocol->port)) == NULL)
867 perror("fetchmail, connecting to host");
873 if (ctl->authenticate == A_KERBEROS)
875 ok = kerberos_auth(fileno(sockfp), ctl->canonical_name);
878 vtalarm(ctl->timeout);
880 #endif /* KERBEROS_V4 */
882 /* accept greeting message from mail server */
883 ok = (protocol->parse_response)(sockfp, buf);
886 vtalarm(ctl->timeout);
888 /* try to get authorized to fetch mail */
889 shroud = ctl->password;
890 ok = (protocol->getauth)(sockfp, ctl, buf);
891 shroud = (char *)NULL;
896 vtalarm(ctl->timeout);
898 /* compute number of messages and number of new messages waiting */
899 ok = (protocol->getrange)(sockfp, ctl, &count, &new);
902 vtalarm(ctl->timeout);
904 /* show user how many messages we downloaded */
905 if (outlevel > O_SILENT)
907 fprintf(stderr, "No mail from %s@%s\n",
909 ctl->servernames->id);
912 fprintf(stderr, "%d message%s", count, count > 1 ? "s" : "");
913 if (new != -1 && (count - new) > 0)
914 fprintf(stderr, " (%d seen)", count-new);
918 ctl->servernames->id);
921 /* we may need to get sizes in order to check message limits */
922 msgsizes = (int *)NULL;
923 if (!ctl->fetchall && proto->getsizes && ctl->limit)
925 msgsizes = (int *)alloca(sizeof(int) * count);
927 ok = (proto->getsizes)(sockfp, count, msgsizes);
930 vtalarm(ctl->timeout);
936 if (new == -1 || ctl->fetchall)
938 ok = ((new > 0) ? PS_SUCCESS : PS_NOMAIL);
944 * What forces this code is that in POP3 and IMAP2BIS you can't
945 * fetch a message without having it marked `seen'. In IMAP4,
946 * on the other hand, you can (peek_capable is set to convey
949 * The result of being unable to peek is that if there's
950 * any kind of transient error (DNS lookup failure, or
951 * sendmail refusing delivery due to process-table limits)
952 * the message will be marked "seen" on the server without
953 * having been delivered. This is not a big problem if
954 * fetchmail is running in foreground, because the user
955 * will see a "skipped" message when it next runs and get
958 * But in daemon mode this leads to the message being silently
959 * ignored forever. This is not acceptable.
961 * We compensate for this by checking the error count from the
962 * previous pass and forcing all messages to be considered new
965 int force_retrieval = !peek_capable && (ctl->errcount > 0);
969 /* read, forward, and delete messages */
970 for (num = 1; num <= count; num++)
972 int toolarge = msgsizes && (msgsizes[num-1] > ctl->limit);
973 int fetch_it = ctl->fetchall ||
974 (!toolarge && (force_retrieval || !(protocol->is_old && (protocol->is_old)(sockfp,ctl,num))));
976 /* we may want to reject this message if it's old */
979 if (outlevel > O_SILENT)
981 fprintf(stderr, "skipping message %d", num);
983 fprintf(stderr, " (oversized, %d bytes)", msgsizes[num-1]);
988 /* request a message */
989 ok = (protocol->fetch)(sockfp, num, &len);
992 vtalarm(ctl->timeout);
994 if (outlevel > O_SILENT)
996 fprintf(stderr, "reading message %d", num);
998 fprintf(stderr, " (%d bytes)", len);
999 if (outlevel == O_VERBOSE)
1000 fputc('\n', stderr);
1005 /* read the message and ship it to the output sink */
1006 ok = gen_readmsg(sockfp,
1008 protocol->delimited,
1012 vtalarm(ctl->timeout);
1014 /* tell the server we got it OK and resynchronize */
1015 if (protocol->trail)
1017 ok = (protocol->trail)(sockfp, ctl, num);
1020 vtalarm(ctl->timeout);
1025 * At this point in flow of control, either we've bombed
1026 * on a protocol error or had delivery refused by the SMTP
1027 * server (unlikely -- I've never seen it) or we've seen
1028 * `accepted for delivery' and the message is shipped.
1029 * It's safe to mark the message seen and delete it on the
1033 /* maybe we delete this message now? */
1034 if (protocol->delete
1035 && (fetch_it ? !ctl->keep : ctl->flush))
1038 if (outlevel > O_SILENT)
1039 fprintf(stderr, " flushed\n");
1040 ok = (protocol->delete)(sockfp, ctl, num);
1043 vtalarm(ctl->timeout);
1044 delete_str(&ctl->newsaved, num);
1046 else if (outlevel > O_SILENT)
1047 fprintf(stderr, " not flushed\n");
1050 /* remove all messages flagged for deletion */
1051 if (protocol->expunge_cmd && deletions > 0)
1053 ok = gen_transact(sockfp, protocol->expunge_cmd);
1056 vtalarm(ctl->timeout);
1059 ok = gen_transact(sockfp, protocol->exit_cmd);
1067 ok = gen_transact(sockfp, protocol->exit_cmd);
1076 vtalarm(ctl->timeout);
1077 if (ok != 0 && ok != PS_SOCKET)
1078 gen_transact(sockfp, protocol->exit_cmd);
1086 fputs("fetchmail: socket", stderr);
1089 fputs("fetchmail: authorization", stderr);
1092 fputs("fetchmail: missing or bad RFC822 header", stderr);
1095 fputs("fetchmail: MDA", stderr);
1098 fputs("fetchmail: client/server synchronization", stderr);
1101 fputs("fetchmail: client/server protocol", stderr);
1104 fputs("fetchmail: SMTP transaction", stderr);
1107 fputs("fetchmail: undefined", stderr);
1110 if (ok==PS_SOCKET || ok==PS_AUTHFAIL || ok==PS_SYNTAX || ok==PS_IOERR
1111 || ok==PS_ERROR || ok==PS_PROTOCOL || ok==PS_SMTP)
1112 fprintf(stderr, " error while talking to %s\n", ctl->servernames->id);
1115 signal(SIGVTALRM, sigsave);
1119 #if defined(HAVE_STDARG_H)
1120 void gen_send(FILE *sockfp, char *fmt, ... )
1121 /* assemble command in printf(3) style and send to the server */
1124 void gen_send(sockfp, fmt, va_alist)
1125 /* assemble command in printf(3) style and send to the server */
1126 FILE *sockfp; /* socket to which server is connected */
1127 const char *fmt; /* printf-style format */
1131 char buf [POPBUFSIZE+1];
1134 if (protocol->tagged)
1135 (void) sprintf(buf, "%s ", GENSYM);
1139 #if defined(HAVE_STDARG_H)
1144 vsprintf(buf + strlen(buf), fmt, ap);
1147 strcat(buf, "\r\n");
1148 SockWrite(buf, strlen(buf), sockfp);
1150 if (outlevel == O_VERBOSE)
1154 if (shroud && (cp = strstr(buf, shroud)))
1155 memset(cp, '*', strlen(shroud));
1156 fprintf(stderr,"> %s", buf);
1160 #if defined(HAVE_STDARG_H)
1161 int gen_transact(FILE *sockfp, char *fmt, ... )
1162 /* assemble command in printf(3) style, send to server, accept a response */
1165 int gen_transact(sockfp, fmt, va_alist)
1166 /* assemble command in printf(3) style, send to server, accept a response */
1167 FILE *sockfp; /* socket to which server is connected */
1168 const char *fmt; /* printf-style format */
1173 char buf [POPBUFSIZE+1];
1176 if (protocol->tagged)
1177 (void) sprintf(buf, "%s ", GENSYM);
1181 #if defined(HAVE_STDARG_H)
1186 vsprintf(buf + strlen(buf), fmt, ap);
1189 strcat(buf, "\r\n");
1190 SockWrite(buf, strlen(buf), sockfp);
1191 if (outlevel == O_VERBOSE)
1195 if (shroud && (cp = strstr(buf, shroud)))
1196 memset(cp, '*', strlen(shroud));
1197 fprintf(stderr,"> %s", buf);
1200 /* we presume this does its own response echoing */
1201 ok = (protocol->parse_response)(sockfp, buf);
1207 /* driver.c ends here */