1 /*
2 * Copyright (c) 2011 QUALCOMM Incorporated. All rights reserved.
3 * The file license.txt specifies the terms for use, modification, or
4 * redistribution.
5 *
6 */
7
8 /*
9 * Revisions:
10 *
11 * 10/13/00 [rcg]
12 * - Fitted LGL's TLS changes.
13 *
14 * 05/23/00 [rcg]
15 * - Fixed case where buffer passed to pop_msg without a format
16 * string.
17 * - EUIDL no longer includes extra newline for single message.
18 *
19 * 03/14/00 [rcg]
20 * - Handle hidden messages in pop_euidl().
21 * - Minor syntactical tweaks.
22 *
23 * 03/01/00 [rcg]
24 * - Handle case of hidden first message.
25 *
26 * 12/03/99 [rcg]:
27 * - 'UIDL x' sent an incorrect UID string if the UID contained
28 * the '%' character, while 'UIDL' worked correctly. This is
29 * because 'UIDL x' sends the response using pop_msg, and used
30 * the UID string as the format string. Now it uses "%s" as
31 * the format string, and the UID string as a parameter.
32 *
33 */
34
35 #include "config.h"
36
37 #include <sys/types.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <sys/file.h>
41 #include <sys/wait.h>
42 #include <ctype.h>
43 #include <string.h>
44
45 #if HAVE_STRINGS_H
46 # include <strings.h>
47 #endif
48
49 #ifndef HAVE_INDEX
50 # define index(s,c) strchr(s,c)
51 #endif
52
53 #include "popper.h"
54
55
56 /*
57 * uidl: POP UIDL function to list messages by message-ids
58 */
59
60 int
pop_uidl(p)61 pop_uidl (p)
62 POP * p;
63 {
64 char buffer [ MAXLINELEN ]; /* Read buffer */
65 char *nl;
66 MsgInfoList *mp; /* Pointer to message info list */
67 int msg_id = 0;
68 int x;
69 int len = 0;
70
71 if ( p->parm_count == 1 ) {
72 len = p->pop_parmlen[1];
73
74 /*
75 * Convert the parameter into an integer
76 */
77 msg_id = atoi ( p->pop_parm[1] );
78 }
79
80 /*
81 * Is requested message out of range?
82 */
83 if ( len > 0 ) {
84 if ( msg_id == 0 )
85 return ( pop_msg ( p, POP_FAILURE, HERE,
86 "Parameter must be a number between 1 and %d",
87 p->msg_count ) );
88
89 /*
90 * Get a pointer to the message in the message list
91 */
92 mp = msg_ptr ( p, msg_id );
93 if ( mp == NULL )
94 return ( pop_msg ( p, POP_FAILURE, HERE,
95 "Message %d out of range.", msg_id ) );
96
97 if ( mp->del_flag )
98 return ( pop_msg ( p, POP_FAILURE, HERE,
99 "Message %d has been marked for deletion.",
100 msg_id ) );
101
102 sprintf ( buffer, "%d %s", msg_id, mp->uidl_str );
103 nl = index ( buffer, NEWLINE );
104 if ( nl != NULL )
105 *nl = 0;
106 return ( pop_msg ( p, POP_SUCCESS, HERE, "%s", buffer ) );
107 } /* msg number specified */
108 else { /* yes, we can do this */
109 pop_msg ( p, POP_SUCCESS, HERE, "uidl command accepted." );
110
111 for ( x = 1; x <= p->msg_count; x++ )
112 {
113 /*
114 * Get a pointer to the message in the message list
115 */
116 mp = msg_ptr ( p, x );
117 if ( mp == NULL )
118 continue;
119
120 /*
121 * Is the message flagged for deletion?
122 */
123 if ( mp->del_flag )
124 continue;
125
126 sprintf ( buffer, "%d %s",
127 mp->visible_num,
128 mp->uidl_str );
129 pop_sendline ( p, buffer );
130 } /* for loop */
131
132 /*
133 * "." signals the end of a multi-line transmission
134 */
135 POP_WRITE_LIT ( p, ".\r\n" );
136 pop_write_flush ( p );
137 } /* do all messages */
138
139 return ( POP_SUCCESS );
140 }
141
142 /*
143 * euidl: POP EUIDL function to list messages by message-ids and adds
144 * message size and From: header text as well. This is to help
145 * the Newton do some pre-filtering before downloading messages.
146 */
147
148 char *
from_hdr(p,mp,buf,len)149 from_hdr ( p, mp, buf, len )
150 POP *p;
151 MsgInfoList *mp;
152 char *buf;
153 size_t len;
154 {
155 char *cp;
156 char *nl;
157
158 fseek ( p->drop, mp->offset, 0 );
159 while ( fgets ( buf, len, p->drop ) != NULL ) {
160 if ( buf[0] == '\n' )
161 break; /* From header not found */
162 if ( !strncasecmp ( "From:", buf, 5 ) ) {
163 cp = index ( buf, ':' );
164 while ( *++cp && ( *cp == ' ' || *cp == '\t' ) );
165 nl = index ( cp, NEWLINE );
166 if ( nl != NULL )
167 *nl = 0;
168 return ( cp );
169 }
170 }
171 return ( "" );
172 }
173
174 int
pop_euidl(p)175 pop_euidl (p)
176 POP * p;
177 {
178 char buffer [ MAXLINELEN ]; /* Read buffer */
179 char fromln [ MAXLINELEN ]; /* Holds 'From:' line */
180 char *nl;
181 MsgInfoList *mp; /* Pointer to message info list */
182 int msg_id = 0;
183 int x;
184 int len = 0;
185
186 if ( p->parm_count == 1 ) {
187 len = p->pop_parmlen[1];
188
189 /*
190 * Convert the parameter into an integer
191 */
192 msg_id = atoi ( p->pop_parm[1] );
193 }
194
195 /*
196 * Is requested message out of range?
197 */
198 if ( len > 0 && msg_id == 0 ) {
199 return ( pop_msg ( p, POP_FAILURE, HERE,
200 "Parameter must be a number (range 1 to %d)",
201 p->visible_msg_count ) );
202 }
203
204 if ( len > 0 && ( msg_id < 1 || msg_id > p->visible_msg_count ) ) {
205 return ( pop_msg ( p, POP_FAILURE, HERE,
206 "Message out of range. %d visible messages in mail drop.",
207 p->visible_msg_count ) );
208 }
209
210 if ( msg_id > 0 ) {
211 /*
212 * Get a pointer to the message in the message list
213 */
214 mp = msg_ptr ( p, msg_id );
215 if ( mp == NULL ) {
216 return ( pop_msg ( p, POP_FAILURE, HERE,
217 "Message %d out of range", msg_id ) );
218 } /* bad msg */
219
220 if ( mp->del_flag ) {
221 return ( pop_msg ( p, POP_FAILURE, HERE,
222 "Message %d has been marked for deletion.",
223 msg_id ) );
224 } /* deleted */
225 else {
226 /*
227 * We have a valid message.
228 */
229 sprintf ( buffer, "%d %s", msg_id, mp->uidl_str );
230 nl = index ( buffer, NEWLINE );
231 if ( nl != NULL )
232 *nl = 0;
233 return ( pop_msg ( p, POP_SUCCESS, HERE, "%s %ld %.128s",
234 buffer, mp->length,
235 from_hdr ( p, mp, fromln, sizeof(fromln) ) ) );
236 } /* valid single message */
237 } /* single message */
238 else {
239 /*
240 * yes, we can do this
241 */
242 pop_msg ( p, POP_SUCCESS, HERE, "uidl command accepted." );
243
244 for ( x = 1; x <= p->msg_count; x++ )
245 {
246 /*
247 * Get a pointer to the message in the message list
248 */
249 mp = msg_ptr ( p, x );
250 if ( mp == NULL )
251 continue;
252
253 /*
254 * Is the message flagged for deletion?
255 */
256 if ( mp->del_flag )
257 continue;
258
259 sprintf ( buffer, "%d %s", x, mp->uidl_str );
260 nl = index ( buffer, NEWLINE );
261 if ( nl != NULL )
262 *nl = 0;
263 sprintf ( buffer, "%s %ld %.128s\n",
264 buffer, mp->length,
265 from_hdr ( p, mp, fromln, sizeof(fromln) ) );
266 pop_sendline ( p, buffer );
267 } /* for loop */
268 } /* all messages */
269
270 /*
271 * "." signals the end of a multi-line transmission
272 */
273 pop_write_line ( p, "." );
274 pop_write_flush ( p );
275
276 return ( POP_SUCCESS );
277 }
278
279