message-send.c revision 6449bd276af37b3e0b81a9c47ecd01f39a2cba53
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2002 Timo Sirainen */
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainenoff_t message_send(struct ostream *output, struct istream *input,
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen uoff_t virtual_skip, uoff_t max_virtual_size, int *last_cr,
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen const unsigned char *msg;
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen unsigned char add;
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen if (max_virtual_size > msg_size->virtual_size - virtual_skip)
0ea17cea21df405e6e74a167d08e1ff0ee95dd13Timo Sirainen max_virtual_size = msg_size->virtual_size - virtual_skip;
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen if (msg_size->physical_size == msg_size->virtual_size && !fix_nuls) {
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen /* no need to kludge with CRs, we can use sendfile() */
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen i_stream_set_read_limit(input, I_MIN(limit, old_limit));
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen message_skip_virtual(input, virtual_skip, NULL, 0, &cr_skipped);
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen /* go through the message data and insert CRs where needed. */
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen i_stream_read_data(input, &msg, &size, 0) > 0) {
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen for (i = 0; i < size && max_virtual_size > 0; i++) {
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen if ((i == 0 && !cr_skipped) ||
d22301419109ed4a38351715e6760011421dadecTimo Sirainen /* missing CR */
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainenvoid message_skip_virtual(struct istream *input, uoff_t virtual_skip,
9740d55b228a670047c854484d5cc979a056a9afTimo Sirainen const unsigned char *msg;
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen while (i_stream_read_data(input, &msg, &size, startpos) > 0) {
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen for (i = startpos; i < size && virtual_skip > 0; i++) {
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen if ((i == 0 && !cr_skipped) ||
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen /* missing CR */
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen /* CR/LF boundary */
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen /* increase after making sure we didn't break
181c1aff950e6f8e0556f8974e79d0747845ac0fTimo Sirainen at virtual \r */
cce169a321c9c629e4f2db1a69dae3b75bbcb27aTimo Sirainen /* leave the last character, it may be \r */