2 * Copyright (c) 1989 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
8 __RCSID("$Heimdal: pop_dropinfo.c 16226 2005-10-22 21:13:53Z lha $"
11 #if defined(UIDL) || defined(XOVER)
14 * Copy the string found after after : into a malloced buffer. Stop
15 * copying at end of string or end of line. End of line delimiter is
16 * not part of the resulting copy.
20 find_value_after_colon(char *p
)
24 for (; *p
!= 0 && *p
!= ':'; p
++) /* Find : */
30 p
++; /* Skip over : */
32 for(; *p
== ' ' || *p
== '\t'; p
++) /* Remove white space */
35 for (t
= p
; *t
!= 0 && *t
!= '\n' && *t
!= '\r'; t
++) /* Find end of str */
38 tmp
= t
= malloc(t
- p
+ 1);
42 for (; *p
!= 0 && *p
!= '\n' && *p
!= '\r'; p
++, t
++) /* Copy characters */
44 *t
= 0; /* Terminate string */
53 parse_header(MsgInfoList
*mp
, char *buffer
)
55 #if defined(UIDL) || defined(XOVER)
56 if (strncasecmp("Message-Id:",buffer
, 11) == 0) {
57 if (mp
->msg_id
== NULL
)
58 mp
->msg_id
= find_value_after_colon(buffer
);
61 else if (strncasecmp(buffer
, "X-UIDL:", 7) == 0) {
62 /* Courtesy to Qualcomm, there really is no such
64 mp
->msg_id
= find_value_after_colon(buffer
);
69 else if (strncasecmp("Subject:", buffer
, 8) == 0) {
70 if(mp
->subject
== NULL
){
72 mp
->subject
= find_value_after_colon(buffer
);
73 for(p
= mp
->subject
; *p
; p
++)
74 if(*p
== '\t') *p
= ' ';
77 else if (strncasecmp("From:", buffer
, 5) == 0) {
80 mp
->from
= find_value_after_colon(buffer
);
81 for(p
= mp
->from
; *p
; p
++)
82 if(*p
== '\t') *p
= ' ';
85 else if (strncasecmp("Date:", buffer
, 5) == 0) {
88 mp
->date
= find_value_after_colon(buffer
);
89 for(p
= mp
->date
; *p
; p
++)
90 if(*p
== '\t') *p
= ' ';
97 add_missing_headers(POP
*p
, MsgInfoList
*mp
)
99 #if defined(UIDL) || defined(XOVER)
100 if (mp
->msg_id
== NULL
) {
101 if (asprintf(&mp
->msg_id
, "no-message-id-%d", mp
->number
) == -1) {
104 return pop_msg (p
,POP_FAILURE
,
105 "Can't build message list for '%s': Out of memory",
111 if (mp
->subject
== NULL
)
112 mp
->subject
= "<none>";
113 if (mp
->from
== NULL
)
114 mp
->from
= "<unknown>";
115 if (mp
->date
== NULL
)
116 mp
->date
= "<unknown>";
122 * dropinfo: Extract information about the POP maildrop and store
123 * it for use by the other POP routines.
129 char buffer
[BUFSIZ
]; /* Read buffer */
130 MsgInfoList
* mp
; /* Pointer to message
132 int msg_num
; /* Current message
134 int nchar
; /* Bytes written/read */
135 int blank_line
= 1; /* previous line was blank */
136 int in_header
= 0; /* if we are in a header block */
138 /* Initialize maildrop status variables in the POP parameter block */
142 p
->bytes_deleted
= 0;
145 /* Allocate memory for message information structures */
146 p
->msg_count
= ALLOC_MSGS
;
147 p
->mlp
= (MsgInfoList
*)calloc((unsigned)p
->msg_count
,sizeof(MsgInfoList
));
151 return pop_msg (p
,POP_FAILURE
,
152 "Can't build message list for '%s': Out of memory", p
->user
);
157 /* Scan the file, loading the message information list with
158 information about each message */
160 for (msg_num
= p
->drop_size
= 0, mp
= p
->mlp
- 1;
161 fgets(buffer
,MAXMSGLINELEN
,p
->drop
);) {
163 nchar
= strlen(buffer
);
165 if (blank_line
&& strncmp(buffer
,"From ",5) == 0) {
167 if (++msg_num
> p
->msg_count
) {
168 p
->mlp
=(MsgInfoList
*) realloc(p
->mlp
,
169 (p
->msg_count
+=ALLOC_MSGS
)*sizeof(MsgInfoList
));
173 return pop_msg (p
,POP_FAILURE
,
174 "Can't build message list for '%s': Out of memory",
177 mp
= p
->mlp
+ msg_num
- 2;
180 mp
->number
= msg_num
;
183 mp
->offset
= ftell(p
->drop
) - nchar
;
185 #if defined(UIDL) || defined(XOVER)
195 pop_log(p
, POP_DEBUG
,
196 "Msg %d at offset %ld being added to list",
197 mp
->number
, mp
->offset
);
200 parse_header(mp
, buffer
);
201 blank_line
= (strncmp(buffer
, "\n", nchar
) == 0);
205 e
= add_missing_headers(p
, mp
);
210 p
->drop_size
+= nchar
;
213 p
->msg_count
= msg_num
;
216 if(p
->debug
&& msg_num
> 0) {
218 for (i
= 0, mp
= p
->mlp
; i
< p
->msg_count
; i
++, mp
++)
221 "Msg %d at offset %ld is %ld octets long and has %u lines and id %s.",
222 mp
->number
,mp
->offset
,mp
->length
,mp
->lines
, mp
->msg_id
);
225 "Msg %d at offset %d is %d octets long and has %u lines.",
226 mp
->number
,mp
->offset
,mp
->length
,mp
->lines
);