Exemplo n.º 1
0
void Bodypart::parseMultipart( uint i, uint end,
                               const EString & rfc2822,
                               const EString & divider,
                               bool digest,
                               List< Bodypart > * children,
                               Multipart * parent,
                               bool pgpSigned )
{
    bool isPgpSigned = pgpSigned;
    uint start = 0;
    bool last = false;
    uint pn = 1;
    while ( !last && i <= end ) {
        if ( i >= end ||
             ( rfc2822[i] == '-' && rfc2822[i+1] == '-' &&
               ( i == 0 || rfc2822[i-1] == 13 || rfc2822[i-1] == 10 ) &&
               rfc2822[i+2] == divider[0] &&
               rfc2822.mid( i+2, divider.length() ) == divider ) )
        {
            uint j = i;
            bool l = false;
            if ( i >= end ) {
                l = true;
            }
            else {
                j = i + 2 + divider.length();
                if ( rfc2822[j] == '-' && rfc2822[j+1] == '-' ) {
                    j += 2;
                    l = true;
                }
            }
            while ( rfc2822[j] == ' ' || rfc2822[j] == '\t' )
                j++;
            if ( rfc2822[j] == 13 || rfc2822[j] == 10 ||
                 j >= rfc2822.length() ) {
                // finally. we accept that as a boundary line.
                if ( rfc2822[j] == 13 )
                    j++;
                if ( rfc2822[j] == 10 )
                    j++;
                if ( start > 0 ) {
                    uint sigstart = start;  // remember original start
                    Header * h = Message::parseHeader( start, j,
                                                       rfc2822,
                                                       Header::Mime );
                    if ( digest )
                        h->setDefaultType( Header::MessageRfc822 );

                    h->repair();

                    // Strip the [CR]LF that belongs to the boundary.
                    if ( rfc2822[i-1] == 10 ) {
                        i--;
                        if ( rfc2822[i-1] == 13 )
                            i--;
                    }
    
                    if ( isPgpSigned ) {
                        // store the complete to-be-signed part, incl. header(s), to keep the unchanged version
                        Bodypart * bpt = new Bodypart( 0, parent );
                        bpt->setData( rfc2822.mid(sigstart, i - sigstart) );
                        bpt->setNumBytes( i - sigstart );
                        children->append( bpt );
                        isPgpSigned = false;
                    }

                    Bodypart * bp =
                        parseBodypart( start, i, rfc2822, h, parent );
                    bp->d->number = pn;
                    children->append( bp );
                    pn++;

                    h->repair( bp, "" );
                }
                last = l;
                start = j;
                i = j;
            }
        }
        while ( i < end && rfc2822[i] != 13 && rfc2822[i] != 10 )
            i++;
        while ( i < end && ( rfc2822[i] == 13 || rfc2822[i] == 10 ) )
            i++;
    }
}
Exemplo n.º 2
0
Injectee * DSN::result() const
{
    Injectee * r = new Injectee;
    Bodypart * plainText = new Bodypart( 1, r );
    Bodypart * dsn = new Bodypart( 2, r );
    Bodypart * original = new Bodypart( 3, r );

    plainText->setParent( r );
    dsn->setParent( r );
    original->setParent( r );
    r->children()->append( plainText );
    r->children()->append( dsn );
    r->children()->append( original );

    // set up the original message, either full or header-only
    if ( fullReport() ) {
        original->header()->add( "Content-Type", "text/rfc822-headers" );
        original->setData( message()->header()->asText() );

        // this is what we _should_ do, except that we don't. the body
        // of the message is lost, probably because original-> has a
        // null parent.

        //original->header()->add( "Content-Type", "message/rfc822" );
        //original->setMessage( message() );

        // and maybe we shouldn't anyway. sending a potentially big
        // body in a bounce is not necessarily a good idea.
    }
    else {
        // nasty mime name there
        original->header()->add( "Content-Type", "text/rfc822-headers" );
        original->setData( message()->header()->asText() );
    }

    // the from field has to contain... what? let's try this for now.
    Address * from = new Address( Configuration::hostname(),
                                  "postmaster",
                                  Configuration::hostname() );
    // set up the top-level header
    Header * h = r->header();
    if ( resultDate() ) {
        h->add( "Date", resultDate()->rfc822() );
    }
    else {
        Date * now = new Date;
        now->setCurrentTime();
        h->add( "Date", now->rfc822() );
    }
    h->add( "From", from->toString() );
    if ( sender() )
        h->add( "To", sender()->toString() );
    if ( allOk() )
        h->add( "Subject", "Message delivered" );
    else if ( allFailed() )
        h->add( "Subject", "Message delivery failed" );
    else
        h->add( "Subject", "Message delivery reports" );
    h->add( "Mime-Version", "1.0" );
    h->add( "Content-Type", "multipart/report; boundary=" +
            Message::acceptableBoundary( message()->rfc822() ) );

    // set up the plaintext and DSN parts
    // what charset should we use for plainText?
    plainText->header()->add( "Content-Type", "text/plain; format=flowed" );
    dsn->header()->add( "Content-Type", "message/delivery-status" );

    plainText->setData( plainBody() );
    dsn->setData( dsnBody() );
    r->addMessageId();

    return r;
}