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_send.c 5476 1999-03-05 14:14:28Z joda $"
12 * sendline: Send a line of a multi-line response to a client.
15 pop_sendline(POP
*p
, char *buffer
)
19 /* Byte stuff lines that begin with the termination octet */
20 if (*buffer
== POP_TERMINATE
)
21 fputc(POP_TERMINATE
,p
->output
);
23 /* Look for a <NL> in the buffer */
24 if ((bp
= strchr(buffer
, '\n')))
27 /* Send the line to the client */
28 fputs(buffer
,p
->output
);
32 pop_log(p
,POP_DEBUG
,"Sending line \"%s\"",buffer
);
35 /* Put a <CR><NL> if a newline was removed from the buffer */
37 fputs ("\r\n",p
->output
);
42 * send: Send the header and a specified number of lines
43 * from a mail message to a POP client.
49 MsgInfoList
* mp
; /* Pointer to message info list */
52 char buffer
[MAXMSGLINELEN
];
53 #ifdef RETURN_PATH_HANDLING
54 char * return_path_adr
;
55 char * return_path_end
;
57 int return_path_linlen
;
61 /* Convert the first parameter into an integer */
62 msg_num
= atoi(p
->pop_parm
[1]);
64 /* Is requested message out of range? */
65 if ((msg_num
< 1) || (msg_num
> p
->msg_count
))
66 return (pop_msg (p
,POP_FAILURE
,"Message %d does not exist.",msg_num
));
68 /* Get a pointer to the message in the message list */
69 mp
= &p
->mlp
[msg_num
-1];
71 /* Is the message flagged for deletion? */
72 if (mp
->flags
& DEL_FLAG
)
73 return (pop_msg (p
,POP_FAILURE
,
74 "Message %d has been deleted.",msg_num
));
76 /* If this is a TOP command, get the number of lines to send */
77 if (strcmp(p
->pop_command
, "top") == 0) {
78 /* Convert the second parameter into an integer */
79 msg_lines
= atoi(p
->pop_parm
[2]);
82 /* Assume that a RETR (retrieve) command was issued */
84 /* Flag the message as retreived */
85 mp
->flags
|= RETR_FLAG
;
88 /* Display the number of bytes in the message */
89 pop_msg(p
, POP_SUCCESS
, "%ld octets", mp
->length
);
92 int e
= pop_maildir_open(p
, mp
);
97 /* Position to the start of the message */
98 fseek(p
->drop
, mp
->offset
, 0);
100 return_path_sent
= 0;
103 /* Skip the first line (the sendmail "From" line) */
104 fgets (buffer
,MAXMSGLINELEN
,p
->drop
);
106 #ifdef RETURN_PATH_HANDLING
107 if (strncmp(buffer
,"From ",5) == 0) {
108 return_path_linlen
= strlen(buffer
);
109 for (return_path_adr
= buffer
+5;
110 (*return_path_adr
== ' ' || *return_path_adr
== '\t') &&
111 return_path_adr
< buffer
+ return_path_linlen
;
114 if (return_path_adr
< buffer
+ return_path_linlen
) {
115 if ((return_path_end
= strchr(return_path_adr
, ' ')) != NULL
)
116 *return_path_end
= '\0';
117 if (strlen(return_path_adr
) != 0 && *return_path_adr
!= '\n') {
118 static char tmpbuf
[MAXMSGLINELEN
+ 20];
119 if (snprintf (tmpbuf
,
122 return_path_adr
) < MAXMSGLINELEN
) {
123 pop_sendline (p
,tmpbuf
);
125 return pop_msg (p
, POP_FAILURE
,
126 "SIGHUP or SIGPIPE flagged");
135 /* Send the header of the message followed by a blank line */
136 while (fgets(buffer
,MAXMSGLINELEN
,p
->drop
)) {
137 #ifdef RETURN_PATH_HANDLING
138 /* Don't send existing Return-Path-header if already sent own */
139 if (!return_path_sent
|| strncasecmp(buffer
, "Return-Path:", 12) != 0)
141 sent_nl
= pop_sendline (p
,buffer
);
142 /* A single newline (blank line) signals the
143 end of the header. sendline() converts this to a NULL,
144 so that's what we look for. */
145 if (*buffer
== 0) break;
147 return (pop_msg (p
,POP_FAILURE
,"SIGHUP or SIGPIPE flagged"));
149 /* Send the message body */
152 while (fgets(buffer
, MAXMSGLINELEN
-1, p
->drop
)) {
153 /* Look for the start of the next message */
154 if (!IS_MAILDIR(p
) && blank_line
&& strncmp(buffer
,"From ",5) == 0)
156 blank_line
= (strncmp(buffer
, "\n", 1) == 0);
157 /* Decrement the lines sent (for a TOP command) */
158 if (msg_lines
>= 0 && msg_lines
-- == 0) break;
159 sent_nl
= pop_sendline(p
,buffer
);
161 return (pop_msg (p
,POP_FAILURE
,"SIGHUP or SIGPIPE flagged"));
163 /* add missing newline at end */
165 fputs("\r\n", p
->output
);
166 /* some pop-clients want a blank line at the end of the
167 message, we always add one here, but what the heck -- in
168 outer (white) space, no one can hear you scream */
170 fputs("\r\n", p
->output
);
172 /* "." signals the end of a multi-line transmission */
173 fputs(".\r\n",p
->output
);