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.
11 * sendline: Send a line of a multi-line response to a client.
14 pop_sendline(POP
*p
, char *buffer
)
18 /* Byte stuff lines that begin with the termination octet */
19 if (*buffer
== POP_TERMINATE
)
20 fputc(POP_TERMINATE
,p
->output
);
22 /* Look for a <NL> in the buffer */
23 if ((bp
= strchr(buffer
, '\n')))
26 /* Send the line to the client */
27 fputs(buffer
,p
->output
);
31 pop_log(p
,POP_DEBUG
,"Sending line \"%s\"",buffer
);
34 /* Put a <CR><NL> if a newline was removed from the buffer */
36 fputs ("\r\n",p
->output
);
41 * send: Send the header and a specified number of lines
42 * from a mail message to a POP client.
48 MsgInfoList
* mp
; /* Pointer to message info list */
51 char buffer
[MAXMSGLINELEN
];
52 #ifdef RETURN_PATH_HANDLING
53 char * return_path_adr
;
54 char * return_path_end
;
56 int return_path_linlen
;
60 /* Convert the first parameter into an integer */
61 msg_num
= atoi(p
->pop_parm
[1]);
63 /* Is requested message out of range? */
64 if ((msg_num
< 1) || (msg_num
> p
->msg_count
))
65 return (pop_msg (p
,POP_FAILURE
,"Message %d does not exist.",msg_num
));
67 /* Get a pointer to the message in the message list */
68 mp
= &p
->mlp
[msg_num
-1];
70 /* Is the message flagged for deletion? */
71 if (mp
->flags
& DEL_FLAG
)
72 return (pop_msg (p
,POP_FAILURE
,
73 "Message %d has been deleted.",msg_num
));
75 /* If this is a TOP command, get the number of lines to send */
76 if (strcmp(p
->pop_command
, "top") == 0) {
77 /* Convert the second parameter into an integer */
78 msg_lines
= atoi(p
->pop_parm
[2]);
81 /* Assume that a RETR (retrieve) command was issued */
83 /* Flag the message as retreived */
84 mp
->flags
|= RETR_FLAG
;
87 /* Display the number of bytes in the message */
88 pop_msg(p
, POP_SUCCESS
, "%ld octets", mp
->length
);
91 int e
= pop_maildir_open(p
, mp
);
96 /* Position to the start of the message */
97 fseek(p
->drop
, mp
->offset
, 0);
102 /* Skip the first line (the sendmail "From" line) */
103 fgets (buffer
,MAXMSGLINELEN
,p
->drop
);
105 #ifdef RETURN_PATH_HANDLING
106 if (strncmp(buffer
,"From ",5) == 0) {
107 return_path_linlen
= strlen(buffer
);
108 for (return_path_adr
= buffer
+5;
109 (*return_path_adr
== ' ' || *return_path_adr
== '\t') &&
110 return_path_adr
< buffer
+ return_path_linlen
;
113 if (return_path_adr
< buffer
+ return_path_linlen
) {
114 if ((return_path_end
= strchr(return_path_adr
, ' ')) != NULL
)
115 *return_path_end
= '\0';
116 if (strlen(return_path_adr
) != 0 && *return_path_adr
!= '\n') {
117 static char tmpbuf
[MAXMSGLINELEN
+ 20];
118 if (snprintf (tmpbuf
,
121 return_path_adr
) < MAXMSGLINELEN
) {
122 pop_sendline (p
,tmpbuf
);
124 return pop_msg (p
, POP_FAILURE
,
125 "SIGHUP or SIGPIPE flagged");
134 /* Send the header of the message followed by a blank line */
135 while (fgets(buffer
,MAXMSGLINELEN
,p
->drop
)) {
136 #ifdef RETURN_PATH_HANDLING
137 /* Don't send existing Return-Path-header if already sent own */
138 if (!return_path_sent
|| strncasecmp(buffer
, "Return-Path:", 12) != 0)
140 sent_nl
= pop_sendline (p
,buffer
);
141 /* A single newline (blank line) signals the
142 end of the header. sendline() converts this to a NULL,
143 so that's what we look for. */
144 if (*buffer
== 0) break;
146 return (pop_msg (p
,POP_FAILURE
,"SIGHUP or SIGPIPE flagged"));
148 /* Send the message body */
151 while (fgets(buffer
, MAXMSGLINELEN
-1, p
->drop
)) {
152 /* Look for the start of the next message */
153 if (!IS_MAILDIR(p
) && blank_line
&& strncmp(buffer
,"From ",5) == 0)
155 blank_line
= (strncmp(buffer
, "\n", 1) == 0);
156 /* Decrement the lines sent (for a TOP command) */
157 if (msg_lines
>= 0 && msg_lines
-- == 0) break;
158 sent_nl
= pop_sendline(p
,buffer
);
160 return (pop_msg (p
,POP_FAILURE
,"SIGHUP or SIGPIPE flagged"));
162 /* add missing newline at end */
164 fputs("\r\n", p
->output
);
165 /* some pop-clients want a blank line at the end of the
166 message, we always add one here, but what the heck -- in
167 outer (white) space, no one can hear you scream */
169 fputs("\r\n", p
->output
);
171 /* "." signals the end of a multi-line transmission */
172 fputs(".\r\n",p
->output
);