]> Pileus Git - ~andy/fetchmail/blob - pop2.c
Complete Dominik's name.
[~andy/fetchmail] / pop2.c
1 /*
2  * pop2.c -- POP2 protocol methods
3  *
4  * Copyright 1997 by Eric S. Raymond
5  * For license terms, see the file COPYING in this directory.
6  */
7
8 #include  "config.h"
9
10 #ifdef POP2_ENABLE
11 #include  <stdio.h>
12 #if defined(STDC_HEADERS)
13 #include <stdlib.h>
14 #endif
15 #ifdef HAVE_STRING_H
16 #include <string.h>
17 #endif
18 #include  "fetchmail.h"
19 #include  "socket.h"
20 #include  "i18n.h"
21
22 static int pound_arg, equal_arg;
23
24 static int pop2_ok (int sock, char *argbuf)
25 /* parse POP2 command response */
26 {
27     int ok;
28     char buf [POPBUFSIZE+1];
29
30     pound_arg = equal_arg = -1;
31
32     if ((ok = gen_recv(sock, buf, sizeof(buf))) == 0)
33     {
34         if (buf[0] == '+')
35             ok = 0;
36         else if (buf[0] == '#')
37         {
38             pound_arg = atoi(buf+1);
39             ok = 0;
40         }
41         else if (buf[0] == '=')
42         {
43             equal_arg = atoi(buf+1);
44             ok = 0;
45         }
46         else if (buf[0] == '-')
47             ok = PS_ERROR;
48         else
49             ok = PS_PROTOCOL;
50
51         if (argbuf != NULL)
52             strcpy(argbuf,buf);
53     }
54
55     return(ok);
56 }
57
58 static int pop2_getauth(int sock, struct query *ctl, char *buf)
59 /* apply for connection authorization */
60 {
61     int status;
62
63     (void)buf;
64
65     if (ctl->sslproto && !strcasecmp(ctl->sslproto, "tls1") && !ctl->use_ssl)
66     {
67         report(stderr, GT_("POP2 does not support STLS. Giving up.\n"));
68         return PS_SOCKET;
69     }
70
71     if (ctl->server.authenticate != A_ANY && ctl->server.authenticate != A_PASSWORD)
72     {
73         report(stderr, GT_("POP2 only supports password authentication. Giving up.\n"));
74         return PS_AUTHFAIL;
75     }
76
77     strlcpy(shroud, ctl->password, sizeof(shroud));
78     status = gen_transact(sock,
79                   "HELO %s %s",
80                   ctl->remotename, ctl->password);
81     memset(shroud, 0x55, sizeof(shroud));
82     shroud[0] = '\0';
83     return status;
84 }
85
86 static int pop2_getrange(int sock, struct query *ctl, const char *folder, 
87                          int *countp, int *newp, int *bytes)
88 /* get range of messages to be fetched */
89 {
90     (void)ctl;
91
92     /* maybe the user wanted a non-default folder */
93     if (folder)
94     {
95         int     ok = gen_transact(sock, "FOLD %s", folder);
96
97         if (ok != 0)
98             return(ok);
99         if (pound_arg == -1)
100             return(PS_ERROR);
101     }
102     else
103         /*
104          * We should have picked up a count of messages in the user's
105          * default inbox from the pop2_getauth() response. 
106          *
107          * Note: this logic only works because there is no way to select
108          * both the unnamed folder and named folders within a single
109          * fetchmail run.  If that assumption ever becomes invalid, the
110          * pop2_getauth code will have to stash the pound response away
111          * explicitly in case it gets stepped on.
112          */
113         if (pound_arg == -1)
114             return(PS_ERROR);
115
116     *countp = pound_arg;
117     *bytes = *newp = -1;
118
119     return(0);
120 }
121
122 static int pop2_fetch(int sock, struct query *ctl, int number, int *lenp)
123 /* request nth message */
124 {
125     int ok;
126
127     (void)ctl;
128     *lenp = 0;
129     ok = gen_transact(sock, "READ %d", number);
130     if (ok)
131         return(0);
132     *lenp = equal_arg;
133
134     gen_send(sock, "RETR");
135
136     return(ok);
137 }
138
139 static int pop2_trail(int sock, struct query *ctl, const char *tag)
140 /* send acknowledgement for message data */
141 {
142     (void)ctl;
143     (void)tag;
144     return(gen_transact(sock, ctl->keep ? "ACKS" : "ACKD"));
145 }
146
147 static int pop2_logout(int sock, struct query *ctl)
148 /* send logout command */
149 {
150     (void)ctl;
151     return(gen_transact(sock, "QUIT"));
152 }
153
154 static const struct method pop2 =
155 {
156     "POP2",                             /* Post Office Protocol v2 */
157     "pop2",                             /* standard POP2 port */
158     "pop2",                             /* ssl POP2 port - not */
159     FALSE,                              /* this is not a tagged protocol */
160     FALSE,                              /* does not use message delimiter */
161     pop2_ok,                            /* parse command response */
162     pop2_getauth,                       /* get authorization */
163     pop2_getrange,                      /* query range of messages */
164     NULL,                               /* no way to get sizes */
165     NULL,                               /* no way to get sizes of subsets */
166     NULL,                               /* messages are always new */
167     pop2_fetch,                         /* request given message */
168     NULL,                               /* no way to fetch body alone */
169     pop2_trail,                         /* eat message trailer */
170     NULL,                               /* no POP2 delete method */
171     NULL,                               /* how to mark a message as seen */
172     NULL,                               /* how to end mailbox processing */
173     pop2_logout,                        /* log out, we're done */
174     FALSE                               /* no, we can't re-poll */
175 };
176
177 int doPOP2 (struct query *ctl)
178 /* retrieve messages using POP2 */
179 {
180     peek_capable = FALSE;
181     return(do_protocol(ctl, &pop2));
182 }
183 #endif /* POP2_ENABLE */
184
185 /* pop2.c ends here */