]> Pileus Git - ~andy/fetchmail/blob - imap.c
Eliminate some unnecessary headers.
[~andy/fetchmail] / imap.c
1 /* 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:       imap.c
8   project:      fetchmail
9   programmer:   Eric S. Raymond
10   description:  IMAP client code
11
12  ***********************************************************************/
13
14 #include  <config.h>
15 #include  <stdio.h>
16 #include  "socket.h"
17 #include  "fetchmail.h"
18
19 /*********************************************************************
20
21  Method declarations for IMAP 
22
23  *********************************************************************/
24
25 static int count, first;
26 static int exists, unseen, recent;
27
28 int imap_ok (argbuf,socket)
29 /* parse command response */
30 char *argbuf;
31 int socket;
32 {
33   int ok;
34   char buf [POPBUFSIZE+1];
35   char *bufp;
36   int n;
37
38   do {
39     if (SockGets(socket, buf, sizeof(buf)) < 0)
40       return(PS_SOCKET);
41
42     if (outlevel == O_VERBOSE)
43       fprintf(stderr,"%s\n",buf);
44
45     /* interpret untagged status responses */
46     if (strstr(buf, "EXISTS"))
47         exists = atoi(buf+2);
48     if (strstr(buf, "RECENT"))
49         recent = atoi(buf+2);
50     if (sscanf(buf + 2, "OK [UNSEEN %d]", &n) == 1)
51         unseen = n;
52
53   } while
54       (tag[0] != '\0' && strncmp(buf, tag, strlen(tag)));
55
56   if (tag[0] == '\0') {
57     strcpy(argbuf, buf);
58     return(0); 
59   }
60   else {
61     if (strncmp(buf + TAGLEN + 1, "OK", 2) == 0) {
62       strcpy(argbuf, buf + TAGLEN);
63       return(0);
64     }
65     else if (strncmp(buf + TAGLEN + 1, "BAD", 2) == 0)
66       return(PS_ERROR);
67     else
68       return(PS_PROTOCOL);
69   }
70 }
71
72 int imap_getauth(socket, queryctl, buf)
73 /* apply for connection authorization */
74 int socket;
75 struct hostrec *queryctl;
76 char *buf;
77 {
78     /* try to get authorized */
79     return(gen_transact(socket,
80                   "LOGIN %s %s",
81                   queryctl->remotename, queryctl->password));
82 }
83
84 static imap_getrange(socket, queryctl, countp, firstp)
85 /* get range of messages to be fetched */
86 int socket;
87 struct hostrec *queryctl;
88 int *countp;
89 int *firstp;
90 {
91     int ok;
92
93     /* find out how many messages are waiting */
94     exists = unseen = recent = -1;
95     ok = gen_transact(socket,
96                   "SELECT %s",
97                   queryctl->remotefolder[0] ? queryctl->remotefolder : "INBOX");
98     if (ok != 0)
99         return(ok);
100
101     /* compute size of message run */
102     *countp = exists;
103     if (queryctl->fetchall)
104         *firstp = 1;
105     else {
106         if (exists > 0 && unseen == -1) {
107             fprintf(stderr,
108                     "no UNSEEN response; assuming all %d RECENT messages are unseen\n",
109                     recent);
110             *firstp = exists - recent + 1;
111         } else {
112             *firstp = unseen;
113         }
114     }
115
116     return(0);
117 }
118
119 static int imap_fetch(socket, number, limit, lenp)
120 /* request nth message */
121 int socket;
122 int number;
123 int limit;
124 int *lenp; 
125 {
126     char buf [POPBUFSIZE+1];
127     int num;
128
129     if (limit) 
130         gen_send(socket,
131                      "PARTIAL %d RFC822 0 %d",
132                      number, limit);
133     else 
134         gen_send(socket,
135                      "FETCH %d RFC822",
136                      number);
137
138     /* looking for FETCH response */
139     do {
140         if (SockGets(socket, buf,sizeof(buf)) < 0)
141             return(PS_SOCKET);
142     } while
143             (sscanf(buf+2, "%d FETCH (RFC822 {%d}", &num, lenp) != 2);
144
145     if (num != number)
146         return(PS_ERROR);
147     else
148         return(0);
149 }
150
151 static imap_trail(socket, queryctl, number)
152 /* discard tail of FETCH response */
153 int socket;
154 struct hostrec *queryctl;
155 int number;
156 {
157     char buf [POPBUFSIZE+1];
158
159     if (SockGets(socket, buf,sizeof(buf)) < 0)
160         return(PS_SOCKET);
161     else
162         return(0);
163 }
164
165 static struct method imap =
166 {
167     "IMAP",                             /* Internet Message Access Protocol */
168     143,                                /* standard IMAP2bis/IMAP4 port */
169     1,                                  /* this is a tagged protocol */
170     0,                                  /* no message delimiter */
171     imap_ok,                            /* parse command response */
172     imap_getauth,                       /* get authorization */
173     imap_getrange,                      /* query range of messages */
174     imap_fetch,                         /* request given message */
175     imap_trail,                         /* eat message trailer */
176     "STORE %d +FLAGS (\\Deleted)",      /* set IMAP delete flag */
177     "EXPUNGE",                          /* the IMAP expunge command */
178     "LOGOUT",                           /* the IMAP exit command */
179 };
180
181 int doIMAP (queryctl)
182 /* retrieve messages using IMAP Version 2bis or Version 4 */
183 struct hostrec *queryctl;
184 {
185     return(do_protocol(queryctl, &imap));
186 }
187
188