1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
/*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#include <popper.h>
RCSID("$Id$");
/*
* sendline: Send a line of a multi-line response to a client.
*/
static int
pop_sendline(POP *p, char *buffer)
{
char * bp;
/* Byte stuff lines that begin with the termination octet */
if (*buffer == POP_TERMINATE)
fputc(POP_TERMINATE,p->output);
/* Look for a <NL> in the buffer */
if ((bp = strchr(buffer, '\n')))
*bp = 0;
/* Send the line to the client */
fputs(buffer,p->output);
#ifdef DEBUG
if(p->debug)
pop_log(p,POP_DEBUG,"Sending line \"%s\"",buffer);
#endif /* DEBUG */
/* Put a <CR><NL> if a newline was removed from the buffer */
if (bp)
fputs ("\r\n",p->output);
return bp != NULL;
}
/*
* send: Send the header and a specified number of lines
* from a mail message to a POP client.
*/
int
pop_send(POP *p)
{
MsgInfoList * mp; /* Pointer to message info list */
int msg_num;
int msg_lines;
char buffer[MAXMSGLINELEN];
#ifdef RETURN_PATH_HANDLING
char * return_path_adr;
char * return_path_end;
int return_path_sent;
int return_path_linlen;
#endif
int sent_nl = 0;
/* Convert the first parameter into an integer */
msg_num = atoi(p->pop_parm[1]);
/* Is requested message out of range? */
if ((msg_num < 1) || (msg_num > p->msg_count))
return (pop_msg (p,POP_FAILURE,"Message %d does not exist.",msg_num));
/* Get a pointer to the message in the message list */
mp = &p->mlp[msg_num-1];
/* Is the message flagged for deletion? */
if (mp->flags & DEL_FLAG)
return (pop_msg (p,POP_FAILURE,
"Message %d has been deleted.",msg_num));
/* If this is a TOP command, get the number of lines to send */
if (strcmp(p->pop_command, "top") == 0) {
/* Convert the second parameter into an integer */
msg_lines = atoi(p->pop_parm[2]);
}
else {
/* Assume that a RETR (retrieve) command was issued */
msg_lines = -1;
/* Flag the message as retreived */
mp->flags |= RETR_FLAG;
}
/* Display the number of bytes in the message */
pop_msg(p, POP_SUCCESS, "%ld octets", mp->length);
if(IS_MAILDIR(p)) {
int e = pop_maildir_open(p, mp);
if(e != POP_SUCCESS)
return e;
}
/* Position to the start of the message */
fseek(p->drop, mp->offset, 0);
return_path_sent = 0;
if(!IS_MAILDIR(p)) {
/* Skip the first line (the sendmail "From" line) */
fgets (buffer,MAXMSGLINELEN,p->drop);
#ifdef RETURN_PATH_HANDLING
if (strncmp(buffer,"From ",5) == 0) {
return_path_linlen = strlen(buffer);
for (return_path_adr = buffer+5;
(*return_path_adr == ' ' || *return_path_adr == '\t') &&
return_path_adr < buffer + return_path_linlen;
return_path_adr++)
;
if (return_path_adr < buffer + return_path_linlen) {
if ((return_path_end = strchr(return_path_adr, ' ')) != NULL)
*return_path_end = '\0';
if (strlen(return_path_adr) != 0 && *return_path_adr != '\n') {
static char tmpbuf[MAXMSGLINELEN + 20];
if (snprintf (tmpbuf,
sizeof(tmpbuf),
"Return-Path: %s\n",
return_path_adr) < MAXMSGLINELEN) {
pop_sendline (p,tmpbuf);
if (hangup)
return pop_msg (p, POP_FAILURE,
"SIGHUP or SIGPIPE flagged");
return_path_sent++;
}
}
}
}
#endif
}
/* Send the header of the message followed by a blank line */
while (fgets(buffer,MAXMSGLINELEN,p->drop)) {
#ifdef RETURN_PATH_HANDLING
/* Don't send existing Return-Path-header if already sent own */
if (!return_path_sent || strncasecmp(buffer, "Return-Path:", 12) != 0)
#endif
sent_nl = pop_sendline (p,buffer);
/* A single newline (blank line) signals the
end of the header. sendline() converts this to a NULL,
so that's what we look for. */
if (*buffer == 0) break;
if (hangup)
return (pop_msg (p,POP_FAILURE,"SIGHUP or SIGPIPE flagged"));
}
/* Send the message body */
{
int blank_line = 1;
while (fgets(buffer, MAXMSGLINELEN-1, p->drop)) {
/* Look for the start of the next message */
if (!IS_MAILDIR(p) && blank_line && strncmp(buffer,"From ",5) == 0)
break;
blank_line = (strncmp(buffer, "\n", 1) == 0);
/* Decrement the lines sent (for a TOP command) */
if (msg_lines >= 0 && msg_lines-- == 0) break;
sent_nl = pop_sendline(p,buffer);
if (hangup)
return (pop_msg (p,POP_FAILURE,"SIGHUP or SIGPIPE flagged"));
}
/* add missing newline at end */
if(!sent_nl)
fputs("\r\n", p->output);
/* some pop-clients want a blank line at the end of the
message, we always add one here, but what the heck -- in
outer (white) space, no one can hear you scream */
if(IS_MAILDIR(p))
fputs("\r\n", p->output);
}
/* "." signals the end of a multi-line transmission */
fputs(".\r\n",p->output);
fflush(p->output);
return(POP_SUCCESS);
}
|