]> Pileus Git - ~andy/fetchmail/blob - pop2.c
16fbb73d5dd649c3161ff226b22ab39a8f3f46ad
[~andy/fetchmail] / pop2.c
1 /* Copyright 1993-95 by Carl Harris, Jr. Copyright 1996 by Eric S. Raymond
2  * All rights reserved.
3  * For license terms, see the file COPYING in this directory.
4  */
5
6 /***********************************************************************
7   module:       pop2.c
8   project:      fetchmail
9   programmer:   Carl Harris, ceharris@mal.com
10                 Hacks and bug fixes by esr.
11   description:  POP2 client code.
12
13  ***********************************************************************/
14
15 #include  <config.h>
16
17 #include  <stdio.h>
18 #if defined(STDC_HEADERS)
19 #include  <string.h>
20 #endif
21 #if defined(HAVE_UNISTD_H)
22 #include  <unistd.h>
23 #endif
24
25 #include  <sys/time.h>
26 #include  <errno.h>
27
28 #include  "socket.h"
29 #include  "fetchmail.h"
30
31 #if HAVE_PROTOTYPES
32 #endif
33
34 /*********************************************************************
35
36  Method declarations for POP2
37
38  *********************************************************************/
39
40 static int pound_arg, equal_arg;
41
42 int pop2_ok (argbuf,socket)
43 /* parse POP2 command response */
44 char *argbuf;
45 int socket;
46 {
47     int ok;
48     char buf [POPBUFSIZE+1];
49
50     pound_arg = equal_arg = -1;
51     if (SockGets(socket, buf, sizeof(buf)) >= 0) {
52         if (outlevel == O_VERBOSE)
53             fprintf(stderr,"%s\n",buf);
54
55         if (buf[0] == '+')
56             ok = 0;
57         else if (buf[0] == '#')
58         {
59             pound_arg = atoi(buf+1);
60             ok = 0;
61         }
62         else if (buf[0] == '=')
63         {
64             equal_arg = atoi(buf+1);
65             ok = 0;
66         }
67         else if (buf[0] == '-')
68             ok = PS_ERROR;
69         else
70             ok = PS_PROTOCOL;
71
72         if (argbuf != NULL)
73             strcpy(argbuf,buf);
74     }
75     else 
76         ok = PS_SOCKET;
77
78     return(ok);
79 }
80
81 int pop2_getauth(socket, queryctl, buf)
82 /* apply for connection authorization */
83 int socket;
84 struct hostrec *queryctl;
85 char *buf;
86 {
87     return(gen_transact(socket,
88                   "HELO %s %s",
89                   queryctl->remotename, queryctl->password));
90 }
91
92 static pop2_getrange(socket, queryctl, countp, firstp)
93 /* get range of messages to be fetched */
94 int socket;
95 struct hostrec *queryctl;
96 int *countp;
97 int *firstp;
98 {
99     /*
100      * We should have picked up a count of messages in the user's
101      * default inbox from the pop2_getauth() response.
102      */
103     if (pound_arg == -1)
104         return(PS_ERROR);
105
106     /* maybe the user wanted a non-default folder */
107     if (queryctl->remotefolder[0])
108     {
109         int     ok = gen_transact(socket, "FOLD %s", queryctl->remotefolder);
110
111         if (ok != 0)
112             return(ok);
113         if (pound_arg == -1)
114             return(PS_ERROR);
115     }
116
117     *firstp = 1;
118     *countp = pound_arg;
119
120     return(0);
121 }
122
123 static int pop2_fetch(socket, number, limit, lenp)
124 /* request nth message */
125 int socket;
126 int number;
127 int limit;
128 int *lenp; 
129 {
130     int ok;
131
132     *lenp = 0;
133     ok = gen_transact(socket, "READ %d", number);
134     if (ok)
135         return(0);
136     *lenp = equal_arg;
137
138     gen_send(socket, "RETR");
139
140     return(ok);
141 }
142
143 static pop2_trail(socket, queryctl, number)
144 /* send acknowledgement for message data */
145 int socket;
146 struct hostrec *queryctl;
147 int number;
148 {
149     return(gen_transact(socket, queryctl->keep ? "ACKS" : "ACKD"));
150 }
151
152 static struct method pop2 =
153 {
154     "POP2",                             /* Post Office Protocol v2 */
155     109,                                /* standard POP2 port */
156     0,                                  /* this is not a tagged protocol */
157     0,                                  /* does not use message delimiter */
158     pop2_ok,                            /* parse command response */
159     pop2_getauth,                       /* get authorization */
160     pop2_getrange,                      /* query range of messages */
161     pop2_fetch,                         /* request given message */
162     pop2_trail,                         /* eat message trailer */
163     NULL,                               /* no POP2 delete command */
164     NULL,                               /* no POP2 expunge command */
165     "QUIT",                             /* the POP2 exit command */
166 };
167
168 int doPOP2 (queryctl)
169 struct hostrec *queryctl;
170 {
171     /* check for unsupported options */
172     if (linelimit) {
173         fprintf(stderr,"Option --limit is not supported with POP2\n");
174         return(PS_SYNTAX);
175     }
176     else if (queryctl->flush) {
177         fprintf(stderr,"Option --flush is not supported with POP2\n");
178         return(PS_SYNTAX);
179     }
180     else if (queryctl->fetchall) {
181         fprintf(stderr,"Option --all is not supported with POP2\n");
182         return(PS_SYNTAX);
183     }
184
185     return(do_protocol(queryctl, &pop2));
186 }