]> Pileus Git - ~andy/fetchmail/blob - etrn.c
Allow the smtphost option to set the host queried for by ETRN.
[~andy/fetchmail] / etrn.c
1 /*
2  * etrn.c -- ETRN protocol methods
3  *
4  * For license terms, see the file COPYING in this directory.
5  */
6
7 #include  <config.h>
8 #include  <stdio.h>
9 #include  "fetchmail.h"
10 #include  "smtp.h"
11 #include  "socket.h"
12
13 static int etrn_ok (FILE *sockfp, char *argbuf)
14 /* parse command response */
15 {
16     int ok;
17     char buf [POPBUFSIZE+1];
18
19     ok = SMTP_ok(sockfp);
20     if (ok == SM_UNRECOVERABLE)
21         return(PS_PROTOCOL);
22     else
23         return(ok);
24 }
25
26 static int etrn_getrange(FILE *sockfp, struct query *ctl, int*countp, int*newp)
27 /* send ETRN and interpret the response */
28 {
29     int ok, opts;
30     char buf [POPBUFSIZE+1];
31
32     if ((ok = SMTP_ehlo(sockfp, ctl->server.names->id, &opts)))
33     {
34         error(0, 0, "%s's SMTP listener does not support ESMTP",
35               ctl->server.names->id);
36         return(ok);
37     }
38     else if (!(opts & ESMTP_ETRN))
39     {
40         error(0, 0, "%s's SMTP listener does not support ETRN",
41               ctl->server.names->id);
42         return(PS_PROTOCOL);
43     }
44
45     *countp = *newp = -1;       /* make sure we don't enter the fetch loop */
46
47     /* ship the actual poll and get the response */
48     gen_send(sockfp, "ETRN %s", ctl->smtphost);
49     if (ok = gen_recv(sockfp, buf, sizeof(buf)))
50         return(ok);
51
52     /* this switch includes all the response codes described in RFC1985 */
53     switch(atoi(buf))
54     {
55     case 250:   /* OK, queuing for node <x> started */
56         error(0, 0, "Queuing for %s started", ctl->server.names->id);
57         break;
58
59     case 251:   /* OK, no messages waiting for node <x> */
60         error(0, 0, "No messages waiting for %s", ctl->server.names->id);
61         return(PS_NOMAIL);
62
63     case 252:   /* OK, pending messages for node <x> started */
64     case 253:   /* OK, <n> pending messages for node <x> started */
65         error(0, 0, "Pending messages for %s started");
66         break;
67
68     case 458:   /* Unable to queue messages for node <x> */
69         error(0, 0, "Unable to queue messages for node %s",
70               ctl->server.names->id);
71         return(PS_PROTOCOL);
72
73     case 459:   /* Node <x> not allowed: <reason> */
74         error(0, 0, "Node %s not allowed: %s", ctl->server.names->id, buf);
75         return(PS_AUTHFAIL);
76
77     case 500:   /* Syntax Error */
78         error(0, 0, "ETRN syntax error");
79         return(PS_PROTOCOL);
80
81     case 501:   /* Syntax Error in Parameters */
82         error(0, 0, "ETRN syntax error in parameters");
83         return(PS_PROTOCOL);
84
85     default:
86         error(0, 0, "Unknown ETRN error");
87         return(PS_PROTOCOL);
88     }
89
90     return(0);
91 }
92
93 const static struct method etrn =
94 {
95     "ETRN",             /* ESMTP ETRN extension */
96     25,                 /* standard SMTP port */
97     FALSE,              /* this is not a tagged protocol */
98     FALSE,              /* this does not use a message delimiter */
99     etrn_ok,            /* parse command response */
100     NULL,               /* no need to get authentication */
101     etrn_getrange,      /* initialize message sending */
102     NULL,               /* we cannot get a list of sizes */
103     NULL,               /* how do we tell a message is old? */
104     NULL,               /* request given message */
105     NULL,               /* no message trailer */
106     NULL,               /* how to delete a message */
107     "QUIT",             /* the ETRN exit command */
108 };
109
110 int doETRN (struct query *ctl)
111 /* retrieve messages using ETRN */
112 {
113     if (ctl->keep) {
114         fprintf(stderr, "Option --keep is not supported with ETRN\n");
115         return(PS_SYNTAX);
116     }
117     if (ctl->flush) {
118         fprintf(stderr, "Option --flush is not supported with ETRN\n");
119         return(PS_SYNTAX);
120     }
121     if (ctl->mailbox) {
122         fprintf(stderr, "Option --remote is not supported with ETRN\n");
123         return(PS_SYNTAX);
124     }
125     if (check_only) {
126         fprintf(stderr, "Option --check is not supported with ETRN\n");
127         return(PS_SYNTAX);
128     }
129     peek_capable = FALSE;
130     return(do_protocol(ctl, &etrn));
131 }
132
133 /* etrn.c ends here */