No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / appl / popper / pop_send.c
blobdac2deb89a9010fa56098595c082c66a910a2d8a
1 /*
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.
5 */
7 #include <popper.h>
8 __RCSID("$Heimdal: pop_send.c 5476 1999-03-05 14:14:28Z joda $"
9 "$NetBSD$");
12 * sendline: Send a line of a multi-line response to a client.
14 static int
15 pop_sendline(POP *p, char *buffer)
17 char * bp;
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')))
25 *bp = 0;
27 /* Send the line to the client */
28 fputs(buffer,p->output);
30 #ifdef DEBUG
31 if(p->debug)
32 pop_log(p,POP_DEBUG,"Sending line \"%s\"",buffer);
33 #endif /* DEBUG */
35 /* Put a <CR><NL> if a newline was removed from the buffer */
36 if (bp)
37 fputs ("\r\n",p->output);
38 return bp != NULL;
41 /*
42 * send: Send the header and a specified number of lines
43 * from a mail message to a POP client.
46 int
47 pop_send(POP *p)
49 MsgInfoList * mp; /* Pointer to message info list */
50 int msg_num;
51 int msg_lines;
52 char buffer[MAXMSGLINELEN];
53 #ifdef RETURN_PATH_HANDLING
54 char * return_path_adr;
55 char * return_path_end;
56 int return_path_sent;
57 int return_path_linlen;
58 #endif
59 int sent_nl = 0;
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]);
81 else {
82 /* Assume that a RETR (retrieve) command was issued */
83 msg_lines = -1;
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);
91 if(IS_MAILDIR(p)) {
92 int e = pop_maildir_open(p, mp);
93 if(e != POP_SUCCESS)
94 return e;
97 /* Position to the start of the message */
98 fseek(p->drop, mp->offset, 0);
100 return_path_sent = 0;
102 if(!IS_MAILDIR(p)) {
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;
112 return_path_adr++)
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,
120 sizeof(tmpbuf),
121 "Return-Path: %s\n",
122 return_path_adr) < MAXMSGLINELEN) {
123 pop_sendline (p,tmpbuf);
124 if (hangup)
125 return pop_msg (p, POP_FAILURE,
126 "SIGHUP or SIGPIPE flagged");
127 return_path_sent++;
132 #endif
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)
140 #endif
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;
146 if (hangup)
147 return (pop_msg (p,POP_FAILURE,"SIGHUP or SIGPIPE flagged"));
149 /* Send the message body */
151 int blank_line = 1;
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)
155 break;
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);
160 if (hangup)
161 return (pop_msg (p,POP_FAILURE,"SIGHUP or SIGPIPE flagged"));
163 /* add missing newline at end */
164 if(!sent_nl)
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 */
169 if(IS_MAILDIR(p))
170 fputs("\r\n", p->output);
172 /* "." signals the end of a multi-line transmission */
173 fputs(".\r\n",p->output);
174 fflush(p->output);
176 return(POP_SUCCESS);