ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:23.99 GB of 70.42 GB (34.07%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ usr/ src/ courier-0.66.1/ rfc2045/ - drwxrwxrwx

Directory:
Viewing file:     rfc2045reply.c (28.32 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 2000-2011 Double Precision, Inc.  See COPYING for
** distribution information.
*/

#include "rfc2045_config.h"
#include    "rfc2045.h"
#include    "rfc2045src.h"
#include    "rfc3676parser.h"
#include    "rfc822/rfc2047.h"
#include    "rfc2045charset.h"
#include    "rfc822/rfc822.h"
#include    "unicode/unicode.h"
#include    <stdio.h>
#include    <unistd.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>


extern void rfc2045_enomem();

static int mkreply(struct rfc2045_mkreplyinfo *);
static int mkforward(struct rfc2045_mkreplyinfo *);

static void mksalutation_datefmt(const char *fmt_start,
                 const char *fmt_end,
                 const char *date,
                 void (*callback_func)(const char *,
                               size_t, void *),
                 void *callback_arg)
{
    time_t t;

    if (!fmt_start)
    {
        fmt_start="%a, %d %b %Y %H:%M:%S %z";
        fmt_end=fmt_start + strlen(fmt_start);
    }

    if ((t=rfc822_parsedt(date)))
    {
        struct tm tmbuf;

        if (localtime_r(&t, &tmbuf))
        {
            char *fmtstr=malloc(fmt_end-fmt_start + 1);

            if (fmtstr)
            {
                char fmtbuf[1024];

                memcpy(fmtstr, fmt_start, fmt_end - fmt_start);
                fmtstr[fmt_end-fmt_start]=0;

                fmtbuf[strftime(fmtbuf,
                        sizeof(fmtbuf)-1,
                        fmtstr, &tmbuf)]=0;

                free(fmtstr);
                (*callback_func)(fmtbuf, strlen(fmtbuf),
                         callback_arg);
                return;
            }
        }
    }
    (*callback_func)(date, strlen(date), callback_arg);
}

static void mksalutation_cb(const char *salutation_template,
                const char *newsgroup,
                const char *message_id,
                const char *newsgroups,
                const char *sender_addr,
                const char *sender_name,
                const char *date,
                const char *subject,

                void (*callback_func)(const char *, size_t, void *),
                void *callback_arg)
{
    const char *p;

    for (p=salutation_template; *p; p++)
    {
        const char *fmt_start=0, *fmt_end=0;

        if (*p != '%' || p[1] == '\0')
        {
            (*callback_func)( p, 1, callback_arg );
            continue;
        }

        ++p;

        if (*p == '{')
        {
            fmt_start= ++p;

            while (*p)
            {
                if (*p == '}')
                {
                    fmt_end=p;
                    ++p;
                    break;
                }
            }

            if (!fmt_end)
                continue;
        }

#define CBSTR(s) s, strlen(s), callback_arg

        switch (*p)    {
        case 'n':
            (*callback_func)("\n", 1, callback_arg );
            continue;
        case 'C':
            (*callback_func)(CBSTR(newsgroup));
            break;
        case 'i':
            (*callback_func)(CBSTR(message_id));
            break;
        case 'N':
            (*callback_func)(CBSTR(newsgroups));
            break;
        case 'f':
            (*callback_func)(CBSTR(sender_addr));
            break;
        case 'F':
            (*callback_func)(CBSTR(sender_name));
            break;
        case 'd':
            mksalutation_datefmt(fmt_start,
                         fmt_end,
                         date,
                         callback_func, callback_arg);
            break;
        case 's':
            (*callback_func)(CBSTR(subject));
            break;
        default:
            (*callback_func)(p, 1, callback_arg);
            break;
        }
#undef CBSTR

    }
}

static void mksal_count(const char *str,
            size_t cnt,
            void *arg)
{
    *(size_t *)arg += cnt;
}

static void mksal_save(const char *str,
               size_t cnt,
               void *arg)
{
    if (cnt)
        memcpy(*(char **)arg, str, cnt);

    *(char **)arg += cnt;
}

static char *mksalutation(const char *salutation_template,
              const char *newsgroup,
              const char *message_id,
              const char *newsgroups,
              const char *sender_addr,
              const char *sender_name,
              const char *date,
              const char *subject,
              const char *charset)
{
    size_t cnt;
    char *p, *q;

    char *subj_decoded=rfc822_display_hdrvalue_tobuf("subject", subject,
                             charset, NULL, NULL);

    if (!subj_decoded)
        return NULL;

    cnt=1;

    mksalutation_cb(salutation_template,
            newsgroup,
            message_id,
            newsgroups,
            sender_addr,
            sender_name,
            date,
            subj_decoded,
            mksal_count, &cnt);

    p=q=malloc(cnt);

    if (!p)
    {
        free(subj_decoded);
        return NULL;
    }

    mksalutation_cb(salutation_template,
            newsgroup,
            message_id,
            newsgroups,
            sender_addr,
            sender_name,
            date,
            subj_decoded,
            mksal_save, &q);
    *q=0;

    free(subj_decoded);
    return p;
}


int rfc2045_makereply(struct rfc2045_mkreplyinfo *ri)
{
    if (strcmp(ri->replymode, "forward") == 0
        || strcmp(ri->replymode, "forwardatt") == 0)
        return (mkforward(ri));

    return (mkreply(ri));
}

struct replyinfostruct {

    struct rfc2045_mkreplyinfo *ri;
    rfc3676_parser_t parser;

    size_t quote_level_adjust;
    size_t quote_level;
    int start_line;
    int isflowed;
    size_t trailing_spaces;
    libmail_u_convert_handle_t u_handle;

};

/*
** Pass original content to the RFC 3676 parser
*/

static int quotereply(const char *p, size_t l, void *voidptr)
{
    struct replyinfostruct *ris=(struct replyinfostruct *)voidptr;

    return rfc3676parser(ris->parser, p, l);
}

/*
** Push formatted reply downstream.
*/

static int output_reply(const char *ptr, size_t cnt, void *arg)
{
    struct replyinfostruct *s=(struct replyinfostruct *)arg;

    (*s->ri->write_func)(ptr, cnt, s->ri->voidarg);
    return 0;
}

/*
** RFC 3676 parser: Start of a new line in the reply.
*/
static int reply_begin(size_t quote_level,
               void *arg)
{
    struct replyinfostruct *s=(struct replyinfostruct *)arg;
    unicode_char quoteChar='>';

    /*
    ** Save quote level, begin conversion from unicode to the native
    ** charset.
    */
    s->quote_level=quote_level+s->quote_level_adjust;

    s->u_handle=libmail_u_convert_init(libmail_u_ucs4_native,
                       s->ri->charset,
                       output_reply,
                       s);

    /*
    ** Emit quoting indentation, if any.
    */
    s->start_line=1;
    s->trailing_spaces=0;

    if (s->u_handle)
    {
        size_t i;

        for (i=0; i<s->quote_level; i++)
        {
            libmail_u_convert_uc(s->u_handle, &quoteChar, 1);
        }
    }
    return 0;
}

/*
** RFC 3676: (possibly partial) contents of a deflowed line, as unicode.
*/

static int reply_contents(const unicode_char *txt,
              size_t txt_size,
              void *arg)
{
    unicode_char spaceChar=' ';
    size_t nonspc_cnt;

    struct replyinfostruct *s=(struct replyinfostruct *)arg;

    if (!s->u_handle || txt_size == 0)
        return 0;

    /*
    ** Space-stuff the initial character.
    */

    if (s->start_line)
    {
        if (!s->isflowed)
        {
            /*
            ** If the original content is not flowed, the rfc3676
            ** parser does not parse the number of > quote
            ** characters and does not set the quote level.
            */

            if ((s->quote_level > 0 && *txt != '>') || *txt == ' ')
                libmail_u_convert_uc(s->u_handle,
                             &spaceChar, 1);

        }
        else
        {
            if (s->quote_level > 0 || *txt == ' ' || *txt == '>')
                libmail_u_convert_uc(s->u_handle,
                             &spaceChar, 1);
        }
        s->start_line=0;
    }

    /*
    ** Trim any trailing spaces from the RFC 3676 parsed content.
    */

    for (nonspc_cnt=txt_size; nonspc_cnt > 0; --nonspc_cnt)
        if (txt[nonspc_cnt-1] != ' ')
            break;

    /*
    ** If the contents are not totally whitespace, it's ok now to emit
    ** any accumulated whitespace from previous content.
    */

    if (nonspc_cnt)
    {
        while (s->trailing_spaces)
        {
            libmail_u_convert_uc(s->u_handle, &spaceChar, 1);
            --s->trailing_spaces;
        }

        libmail_u_convert_uc(s->u_handle, txt, nonspc_cnt);
    }

    s->trailing_spaces += txt_size - nonspc_cnt;
    return 0;
}

static int reply_end(void *arg)
{
    unicode_char newLine='\n';
    struct replyinfostruct *s=(struct replyinfostruct *)arg;

    libmail_u_convert_uc(s->u_handle, &newLine, 1);

    libmail_u_convert_deinit(s->u_handle, NULL);
    return 0;
}

/*
** RFC 3676 parser: flowed line break. Replicate it.
*/
static int reply_wrap(void *arg)
{
    unicode_char spaceChar=' ';
    struct replyinfostruct *s=(struct replyinfostruct *)arg;

    /*
    ** It's safe to preserve trailing spaces on flowed lines.
    */

    while (s->trailing_spaces)
    {
        libmail_u_convert_uc(s->u_handle, &spaceChar, 1);
        --s->trailing_spaces;
    }

    libmail_u_convert_uc(s->u_handle, &spaceChar, 1);
    reply_end(s);
    reply_begin(s->quote_level-s->quote_level_adjust, s);
    /* Undo the adjustment in reply_begin() */

    return 0;
}

static void reformat(struct rfc2045_mkreplyinfo *ri, struct rfc2045 *rfc,
             size_t adjustLevel)
{
    struct replyinfostruct ris;

    struct rfc3676_parser_info info;
    int conv_err;

    ris.ri=ri;
    ris.quote_level_adjust=adjustLevel;

    memset(&info, 0, sizeof(info));

    info.charset=ri->charset;
    ris.isflowed=info.isflowed=rfc2045_isflowed(rfc);
    info.isdelsp=rfc2045_isdelsp(rfc);

    info.line_begin=reply_begin;
    info.line_contents=reply_contents;
    info.line_flowed_notify=reply_wrap;
    info.line_end=reply_end;
    info.arg=&ris;

    if ((ris.parser=rfc3676parser_init(&info)) != NULL)
    {
        rfc2045_decodetextmimesection(ri->src, rfc,
                          ri->charset,
                          &conv_err,
                          quotereply,
                          &ris);
        rfc3676parser_deinit(ris.parser, NULL);
    }
}

static void    replybody(struct rfc2045_mkreplyinfo *ri, struct rfc2045 *rfc)
{
    rfc=rfc2045_searchcontenttype(rfc, "text/plain");

    if (!rfc)
        return;

    reformat(ri, rfc, 1);
}

static void writes(struct rfc2045_mkreplyinfo *ri, const char *c)
{
    (*ri->write_func)(c, strlen(c), ri->voidarg);
}

static void forwardbody(struct rfc2045_mkreplyinfo *ri, long nbytes)
{
    char    buf[BUFSIZ];
    ssize_t i;

    while ((i=nbytes > sizeof(buf) ? sizeof(buf):nbytes) > 0 &&
           (i=SRC_READ(ri->src, buf, i)) > 0)
    {
        nbytes -= i;
        (*ri->write_func)(buf, i, ri->voidarg);
    }
}

/*
** Format a forward
*/
static int mkforward(struct rfc2045_mkreplyinfo *ri)
{
    off_t    start_pos, end_pos, start_body;
    off_t    dummy;

    char    *header, *value;
    char    *subject=0;

    char    *boundary=0;

    struct rfc2045headerinfo *hi;

    struct    rfc2045 *textplain_content;
    struct    rfc2045 *first_attachment;
    int attachment_is_message_rfc822;

    /*
    ** Use the original message's subject to set the subject of the
    ** forward message.
    */

    hi=rfc2045header_start(ri->src, ri->rfc2045partp);

    if (!hi)
        return (-1);

    for (;;)
    {
        if (rfc2045header_get(hi, &header, &value, 0))
        {
            rfc2045header_end(hi);
            return (-1);
        }

        if (!header)
            break;
        if (strcmp(header, "subject") == 0)
        {
            if (subject)    free(subject);

            subject=strdup(value);
            if (!subject)
            {
                rfc2045header_end(hi);
                return (-1);
            }
        }
    }

    rfc2045header_end(hi);

    writes(ri, "Subject: ");

    if (ri->subject)
    {
        /*
        ** ... unless the caller overrides it.
        */

        writes(ri, ri->subject);
    }
    else if (subject)
    {
        char    *s=rfc822_coresubj_keepblobs(subject);

        if (!s)
            return (-1);

        writes(ri, s);
        free(s);
        writes(ri, " (fwd)");
    }
    writes(ri, "\nMime-Version: 1.0\n");

    /*
    ** To assemble a forward template, two things are needed:
    **
    ** 1. The original message, as text/plain.
    **
    ** 2. Any attachments in the original message.
    **    A. The attachments get either copied to the forward message, or
    **    B. The original message is attached as a single message/rfc822
    **       entity.
    **
    ** 2b is always produced by "forwardatt". If a suitable text/plain
    ** part of the original message could not be found, 2b is also
    ** produced even by "forward".
    */

    textplain_content=NULL;

    attachment_is_message_rfc822=0;
    first_attachment=NULL;

    {
        const char *content_type, *dummy;

        struct rfc2045 *top_part=ri->rfc2045partp;

        rfc2045_mimeinfo(top_part,
                 &content_type, &dummy, &dummy);

        if (strcmp(content_type, "multipart/signed") == 0)
        {
            struct rfc2045 *p=top_part->firstpart;

            if (p && p->isdummy)
                p=p->next;

            if (p)
            {
                top_part=p;
                rfc2045_mimeinfo(top_part,
                         &content_type, &dummy, &dummy);
            }
        }
        else if (strcmp(content_type, "multipart/x-mimegpg") == 0)
        {
            struct rfc2045 *p=top_part->firstpart;

            if (p && p->isdummy)
                p=p->next;

            if (p)
            {
                const char *part_ct;

                rfc2045_mimeinfo(p,
                         &part_ct, &dummy, &dummy);

                if (strcmp(part_ct, "text/x-gpg-output") == 0
                    && p->next)
                {
                    top_part=p->next;
                    rfc2045_mimeinfo(top_part,
                             &content_type,
                             &dummy, &dummy);
                }
            }
        }

        if (strcmp(content_type, "text/plain") == 0)
        {
            textplain_content=top_part;
        }
        else if (strcmp(content_type, "multipart/alternative") == 0)
        {
            textplain_content=
                rfc2045_searchcontenttype(top_part,
                              "text/plain");
        }
        else if (strcmp(content_type, "multipart/mixed") == 0)
        {
            struct rfc2045 *p=top_part->firstpart;

            if (p->isdummy)
                p=p->next;

            textplain_content=
                rfc2045_searchcontenttype(p, "text/plain");

            /*
            ** If the first part contained a suitable text/plain,
            ** any remaining MIME parts become attachments that
            ** get copied to the forward message.
            */
            if (textplain_content)
                first_attachment=p->next;
        }

        if (strcmp(ri->replymode, "forwardatt") == 0 ||
            textplain_content == NULL)
        {
            /*
            ** Copy the entire message as the sole message/rfc822
            ** attachment in the forward message.
            */
            textplain_content=NULL;
            first_attachment=top_part;
            attachment_is_message_rfc822=1;
        }
    }

    boundary=strdup(rfc2045_mk_boundary(ri->rfc2045partp, ri->src));
    if (!boundary)
    {
        if (subject)    free(subject);
        return (-1);
    }

    if (first_attachment)
    {
        writes(ri, "Content-Type: multipart/mixed; boundary=\"");
        writes(ri, boundary);
        writes(ri, "\"\n\n");
        writes(ri, RFC2045MIMEMSG);
        writes(ri, "\n--");
        writes(ri, boundary);
        writes(ri, "\n");
    }

    if (ri->content_set_charset)
    {
        (*ri->content_set_charset)(ri->voidarg);
    }
    else
    {
        writes(ri, "Content-Type: text/plain; format=flowed; delsp=yes; charset=\"");
        writes(ri, ri->charset);
        writes(ri, "\"\n");
    }

    writes(ri, "Content-Transfer-Encoding: 8bit\n\n");
    if (ri->content_specify)
        (*ri->content_specify)(ri->voidarg);

    writes(ri, "\n");
    if (ri->writesig_func)
        (*ri->writesig_func)(ri->voidarg);
    writes(ri, "\n");

    if (ri->forwardsep)
    {
        writes(ri, ri->forwardsep);
        writes(ri, "\n");
    }

    if (textplain_content)
    {
        /* Copy original headers. */
        
        hi=rfc2045header_start(ri->src, ri->rfc2045partp);
        for (;;)
        {
            if (rfc2045header_get(hi, &header, &value,
                          RFC2045H_NOLC|RFC2045H_KEEPNL))
            {
                rfc2045header_end(hi);
                break;
            }
            if (!header)
                break;
            if (strcasecmp(header, "subject") == 0 ||
                strcasecmp(header, "from") == 0 ||
                strcasecmp(header, "to") == 0 ||
                strcasecmp(header, "cc") == 0 ||
                strcasecmp(header, "date") == 0 ||
                strcasecmp(header, "message-id") == 0 ||
                strcasecmp(header, "resent-from") == 0 ||
                strcasecmp(header, "resent-to") == 0 ||
                strcasecmp(header, "resent-cc") == 0 ||
                strcasecmp(header, "resent-date") == 0 ||
                strcasecmp(header, "resent-message-id") == 0)
            {
                if (subject) free(subject);

                subject=rfc822_display_hdrvalue_tobuf(header,
                                      value,
                                      ri->charset,
                                      NULL,
                                      NULL);

                if (subject)
                {
                    (*ri->write_func)(header,
                              strlen(header),
                              ri->voidarg);
                    (*ri->write_func)(": ", 2, ri->voidarg);
                    (*ri->write_func)(subject,
                              strlen(subject),
                              ri->voidarg);
                    (*ri->write_func)("\n", 1, ri->voidarg);
                }
            }
        }
        rfc2045header_end(hi);
        (*ri->write_func)("\n", 1, ri->voidarg);

        reformat(ri, textplain_content, 0);
    }

    if (first_attachment)
    {
        /*
        ** There are attachments to copy
        */

        if (attachment_is_message_rfc822)
        {
            /* Copy everything as a message/rfc822 */

            writes(ri, "\n--");
            writes(ri, boundary);
            writes(ri, "\nContent-Type: message/rfc822\n");

            if (ri->forwarddescr)
            {
                char *p=rfc2047_encode_str(ri->forwarddescr,
                               ri->charset ?
                               ri->charset
                               : "iso-8859-1",
                               rfc2047_qp_allow_any
                               );

                writes(ri, "Content-Description: ");
                writes(ri, p ? p:"");
                free(p);
                writes(ri, "\n");
            }

            writes(ri, "\n");

            rfc2045_mimepos(first_attachment, &start_pos, &end_pos,
                    &start_body,
                    &dummy, &dummy);
            
            if (SRC_SEEK(ri->src, start_pos) == (off_t)-1)
            {
                if (subject) free(subject);
                free(boundary);
                return -1;
            }
            forwardbody(ri, end_pos - start_pos);
        }
        else
        {
            /* Copy over individual attachments, one by one */

            for (; first_attachment;
                 first_attachment=first_attachment->next)
            {
                writes(ri, "\n--");
                writes(ri, boundary);
                writes(ri, "\n");

                rfc2045_mimepos(first_attachment, &start_pos,
                        &end_pos,
                        &start_body,
                        &dummy, &dummy);
            
                if (SRC_SEEK(ri->src, start_pos) == (off_t)-1)
                {
                    if (subject) free(subject);
                    free(boundary);
                    return -1;
                }

                forwardbody(ri, end_pos - start_pos);
            }
        }

        writes(ri, "\n--");
        writes(ri, boundary);
        writes(ri, "--\n");
    }

    if (subject) free(subject);
    free(boundary);
    return (0);
}


static int writereferences(struct rfc2045_mkreplyinfo *ri,
                const char *oldref, const char *oldmsgid)
{
char    *buf=malloc((oldref ? strlen(oldref):0)
        + (oldmsgid ? strlen(oldmsgid):0)+2);
char    *p, *q;
struct    rfc822t *tp;
struct    rfc822a *ap;
int    i;

    if (!buf)
        return (-1);

    /* Create new references header */
    *buf=0;
    if (oldref)    strcat(buf, oldref);
    if (oldref && oldmsgid)    strcat(buf, " ");
    if (oldmsgid)    strcat(buf, oldmsgid);

    /* Do wrapping the RIGHT way, by
    ** RFC822 parsing the References: header
    */

    if ((tp=rfc822t_alloc_new(buf, NULL, NULL)) == 0 ||
        (ap=rfc822a_alloc(tp)) == 0)
    {
        free(buf);
        if (tp)
            rfc822t_free(tp);
        return (-1);
    }

    /* Keep only the last 20 message IDs */

    i=0;
    if (ap->naddrs > 20)    i=ap->naddrs-20;
    p="";
    while (i < ap->naddrs)
    {
        q=rfc822_gettok(ap->addrs[i].tokens);
        if (!q)
        {
            rfc822a_free(ap);
            rfc822t_free(tp);
            free(buf);
            return (-1);
        }

        writes(ri, p);
        writes(ri, "<");
        writes(ri, q);
        writes(ri, ">\n");
        p="            ";
        free(q);
        i++;
    }
    rfc822a_free(ap);
    rfc822t_free(tp);
    free(buf);
    return (0);
}

static char *mlcheck(struct rfc2045_mkreplyinfo *ri, const char *);

static int mkreply(struct rfc2045_mkreplyinfo *ri)
{
    char    *oldtocc, *oldfrom, *oldreplyto, *oldtolist;
    char    *subject;
    char    *oldmsgid;
    char    *oldreferences;
    char    *oldenvelope;
    char    *header, *value;
    char    *date;
    char    *newsgroup;
    char    *newsgroups;

    char    *whowrote;
    off_t    start_pos, end_pos, start_body, dummy;
    int errflag=0;
    char    *boundary;

    struct rfc2045headerinfo *hi;

    oldtocc=0;
    oldtolist=0;
    oldfrom=0;
    oldreplyto=0;
    subject=0;
    oldmsgid=0;
    oldreferences=0;
    oldenvelope=0;
    whowrote=0;
    newsgroup=0;
    newsgroups=0;
    date=0;

    rfc2045_mimepos(ri->rfc2045partp, &start_pos, &end_pos, &start_body,
        &dummy, &dummy);

    hi=rfc2045header_start(ri->src, ri->rfc2045partp);

    if (!hi)
        return (-1);

#define BLOWUP { \
        if (whowrote) free(whowrote); \
        if (subject) free(subject); \
        if (oldmsgid) free(oldmsgid); \
        if (oldreferences)    free(oldreferences); \
        if (oldtocc) free(oldtocc); \
        if (oldtolist) free(oldtolist); \
        if (oldfrom) free(oldfrom); \
        if (oldreplyto)    free(oldreplyto); \
        if (oldenvelope) free(oldenvelope); \
        if (newsgroup) free(newsgroup); \
        if (newsgroups) free(newsgroups); \
        if (date) free(date); \
        rfc2045header_end(hi); \
        return (-1); \
    }

    for (;;)
    {
        if (rfc2045header_get(hi, &header, &value, 0))
        {
            BLOWUP;
            return (-1);
        }

        if (!header)
            break;

        if (strcmp(header, "subject") == 0)
        {
            if (subject)    free(subject);

            subject=strdup(value);
            if (!subject)
                BLOWUP;
        }
        else if (strcmp(header, "reply-to") == 0)
        {
            if (oldreplyto)    free(oldreplyto);
            oldreplyto=strdup(value);
            if (!oldreplyto)
                BLOWUP;
        }
        else if (strcmp(header, "from") == 0)
        {
            if (oldfrom)    free(oldfrom);
            oldfrom=strdup(value);
            if (!oldfrom)
                BLOWUP;
        }
        else if (strcmp(header, "message-id") == 0)
        {
            if (oldmsgid)    free(oldmsgid);
            oldmsgid=strdup(value);
            if (!oldmsgid)
                BLOWUP;
        }
        else if (strcmp(header, "references") == 0)
        {
            if (oldreferences)    free(oldreferences);
            oldreferences=strdup(value);
            if (!oldreferences)
                BLOWUP;
        }
        else if ((strcmp(header, "return-path") == 0 ||
              strcmp(header, "errors-to") == 0) &&
             ri->replytoenvelope)
        {
            if (oldenvelope)    free(oldenvelope);
            oldenvelope=strdup(value);
            if (!oldenvelope)
                BLOWUP;
        }
        else if (strcmp(header, "newsgroups") == 0)
        {
            if (newsgroups)    free(newsgroups);
            newsgroups=strdup(value);
            if (!newsgroups)
                BLOWUP;
        }
        else if (strcmp(header, "x-newsgroup") == 0)
        {
            if (newsgroup)    free(newsgroup);
            newsgroup=strdup(value);
            if (!newsgroup)
                BLOWUP;
        }
        else if (strcmp(header, "date") == 0)
        {
            if (date)    free(date);
            date=strdup(value);
            if (!date)
                BLOWUP;
        }
        else if ((strcmp(ri->replymode, "replyall") == 0
              || strcmp(ri->replymode, "replylist") == 0) &&
             (
              strcmp(header, "to") == 0 ||
              strcmp(header, "cc") == 0
              )
             )
        {
            char    *newh=malloc( (oldtocc ?
                           strlen(oldtocc):0)
                          + strlen(value)+2);
            char    *p;

                if (!newh)
                    BLOWUP;

                *newh=0;
                if (oldtocc)
                    strcat(strcpy(newh, oldtocc),
                                ",");
                strcat(newh, value);
                if (oldtocc)    free(oldtocc);
                oldtocc=newh;

                p=mlcheck(ri, value);
                if (!p || (newh=malloc((oldtolist ?
                               strlen(oldtolist):0)
                       + strlen(p)+2)) == NULL)
                {
                    if (p)
                        free(p);
                    BLOWUP;
                }

                if (*p)
                {
                    *newh=0;
                    if (oldtolist)
                        strcat(strcpy(newh, oldtolist),
                               ",");
                    strcat(newh, p);
                    if (oldtolist)
                        free(oldtolist);
                    oldtolist=newh;
                }
                free(p);
        }
    }

    rfc2045header_end(hi);

    /* Write:  "%s writes:" */

    {
        struct    rfc822t *rfcp=rfc822t_alloc_new(oldfrom ? oldfrom:"",
                            NULL, NULL);
        struct    rfc822a *rfcpa;
        char    *sender_name=NULL;
        char    *sender_addr=NULL;
        int    n;

        if (!rfcp)
            BLOWUP;

        rfcpa=rfc822a_alloc(rfcp);
        if (!rfcpa)
        {
            rfc822t_free(rfcp);
            BLOWUP;
        }

        for (n=0; n<rfcpa->naddrs; ++n)
        {
            if (rfcpa->addrs[n].tokens == NULL)
                continue;

            sender_name=rfc822_display_name_tobuf(rfcpa, n,
                                  ri->charset);
            sender_addr=rfc822_display_addr_tobuf(rfcpa, n,
                                  ri->charset);
            break;
        }

        rfc822a_free(rfcpa);
        rfc822t_free(rfcp);

        whowrote=mksalutation(ri->replysalut,
                      newsgroup ? newsgroup:"",
                      oldmsgid ? oldmsgid:"",
                      newsgroups ? newsgroups:"",

                      sender_addr ? sender_addr:"(no address given)",
                      sender_name ? sender_name:sender_addr,
                      date,
                      subject,
                      ri->charset);

        if (sender_name)
            free(sender_name);
        if (sender_addr)
            free(sender_addr);

        if (!whowrote)
        {
            BLOWUP;
        }
    }

    if (newsgroups)
        free(newsgroups);
    if (newsgroup)
        free(newsgroup);
    if (date)
        free(date);
    if (oldreplyto)
    {
        if (oldfrom)    free(oldfrom);
        oldfrom=oldreplyto;
        oldreplyto=0;
    }

    if (oldenvelope)
    {
        if (oldfrom)    free(oldfrom);
        oldfrom=oldenvelope;
        oldenvelope=0;
    }

    /*
    ** Replytolist: if we found mailing list addresses, drop
    ** oldtocc, we'll use oldtolist.
    ** Otherwise, drop oldtolist.
    */

    if (strcmp(ri->replymode, "replylist") == 0)
    {
        if (oldtolist)
        {
            if (oldtocc)
            {
                free(oldtocc);
                oldtocc=0;
            }

            if (oldfrom)
            {
                free(oldfrom);
                oldfrom=0;
            }
        }
    }
    else
    {
        if (oldtolist)
        {
            free(oldtolist);
            oldtolist=NULL;
        }
    }

    /* Remove duplicate entries from new Cc header */

    if (oldtocc)
    {
        struct rfc822t    *rfccc, *rfcto;
        struct rfc822a    *arfccc, *arfcto;
        int    i, j;
        char    *new_addresses;

        rfccc=rfc822t_alloc_new(oldtocc, NULL, NULL);
        rfcto= oldfrom ? rfc822t_alloc_new(oldfrom, NULL,
                           NULL):NULL;
        arfccc=rfccc ? rfc822a_alloc(rfccc):NULL;
        arfcto=rfcto ? rfc822a_alloc(rfcto):NULL;

        for (i=0; arfccc && i <arfccc->naddrs; i++)
        {
            char    *addr=rfc822_getaddr(arfccc, i);

            if (!addr)    continue;

                /* Remove address from Cc if it is my address */

            if ( (ri->myaddr_func)(addr, ri->voidarg))
            {
                rfc822_deladdr(arfccc, i); --i;
                free(addr);
                continue;
            }

                /* Remove address from Cc if it appears in To: */

            for (j=0; arfcto && j < arfcto->naddrs; j++)
            {
                char *addr2=rfc822_getaddr(arfcto, j);

                if (!addr2)    continue;
                if (strcmp(addr, addr2) == 0)
                {
                    free(addr2);
                    break;
                }
                free(addr2);
            }
            if (arfcto && j < arfcto->naddrs)
            {
                rfc822_deladdr(arfccc, i); --i;
                free(addr);
                continue;
            }

                /* Remove outright duplicates in Cc */

            for (j=i+1; j<arfccc->naddrs; j++)
            {
                char *addr2=rfc822_getaddr(arfccc, j);

                if (!addr2)    continue;
                if (strcmp(addr, addr2) == 0)
                {
                    rfc822_deladdr(arfccc, j);
                    --j;
                }
                free(addr2);
            }
            free(addr);
        }
        new_addresses=rfc822_getaddrs(arfccc);
        free(oldtocc);
        oldtocc=new_addresses;
        if (arfccc)    rfc822a_free(arfccc);
        if (arfcto)    rfc822a_free(arfcto);
        rfc822t_free(rfccc);
        if (rfcto) rfc822t_free(rfcto);
    }

    if (oldtolist)
    {
        writes(ri, "To: ");
        writes(ri, oldtolist);
        writes(ri, "\n");
        free(oldtolist);
    }

    if (oldfrom)
    {
        writes(ri, "To: ");
        writes(ri, oldfrom);
        writes(ri, "\n");
        free(oldfrom);
    }

    if (oldtocc)
    {
        writes(ri, "Cc: ");
        writes(ri, oldtocc);
        writes(ri, "\n");
        free(oldtocc);
    }

    if (oldmsgid || oldreferences)
    {
        writes(ri, "References: ");
        if (writereferences(ri, oldreferences, oldmsgid))
            errflag= -1;
        if (oldreferences)    free(oldreferences);
    }
    if (oldmsgid)
    {
        writes(ri, "In-Reply-To: ");
        writes(ri, oldmsgid);
        writes(ri, "\n");
        free(oldmsgid);
    }
    writes(ri,"Subject: ");

    if (ri->subject)
    {
        writes(ri, ri->subject);
    }
    else if (subject)
    {
        char    *s=rfc822_coresubj_keepblobs(subject);

        writes(ri, "Re: ");
        writes(ri, s ? s:"");
        if (s)    free(s);
        free(subject);
    }

    writes(ri, "\nMime-Version: 1.0\n");


    boundary=NULL;

    if (strcmp(ri->replymode, "replydsn") == 0 && ri->dsnfrom)
    {
        boundary=rfc2045_mk_boundary(ri->rfc2045partp, ri->src);
        if (!boundary)
            return (-1);

        writes(ri, "Content-Type: multipart/report;"
               " report-type=delivery-status;\n"
               "    boundary=\"");

        writes(ri, boundary);

        writes(ri,"\"\n"
            "\n"
            RFC2045MIMEMSG
            "\n"
               "--");
        writes(ri, boundary);
        writes(ri, "\n");
    }

    if (ri->content_set_charset)
    {
        (*ri->content_set_charset)(ri->voidarg);
    }
    else
    {
        writes(ri, "Content-Type: text/plain; format=flowed; delsp=yes; charset=\"");
        writes(ri, ri->charset);
        writes(ri, "\"\n");
    }
    writes(ri, "Content-Transfer-Encoding: 8bit\n\n");

    if (!ri->donotquote)
    {
        if (whowrote)
        {
            writes(ri, whowrote);
            free(whowrote);
            writes(ri, "\n\n");
        }
        if (SRC_SEEK(ri->src, start_body) == (off_t)-1)
            return (-1);

        replybody(ri, ri->rfc2045partp);
        writes(ri, "\n");    /* First blank line in the reply */
    }

    if (ri->content_specify)
        (*ri->content_specify)(ri->voidarg);

    writes(ri, "\n");
    if (ri->writesig_func)
        (*ri->writesig_func)(ri->voidarg);
    writes(ri, "\n");

    if (boundary)
    {
        char    *header, *value;
        struct rfc2045headerinfo *hi;

        time_t now;

        time(&now);

        writes(ri, "\n--");
        writes(ri, boundary);
        writes(ri, "\nContent-Type: message/delivery-status\n"
               "Content-Transfer-Encoding: 7bit\n\n"
               "Arrival-Date: ");

        writes(ri, rfc822_mkdate(now));
        writes(ri,"\n"
               "\n"
               "Final-Recipient: rfc822; ");

        writes(ri, ri->dsnfrom);

        writes(ri, "\n"
               "Action: delivered\n"
               "Status: 2.0.0\n"
               "\n--");
        writes(ri, boundary);
        writes(ri, "\nContent-Type: text/rfc822-headers; charset=\"iso-8859-1\"\n"
               "Content-Disposition: attachment\n"
               "Content-Transfer-Encoding: 8bit\n\n"
               );

        hi=rfc2045header_start(ri->src, ri->rfc2045partp);

        while (hi)
        {
            if (rfc2045header_get(hi, &header, &value,
                          RFC2045H_NOLC) || !header)
            {
                rfc2045header_end(hi);
                break;
            }

            writes(ri, header);
            writes(ri, ": ");
            writes(ri, value);
            writes(ri, "\n");
        }
        writes(ri, "\n--");
        writes(ri, boundary);
        writes(ri, "--\n");
        free(boundary);
    }
    return (errflag);
}

/*
** Accept a list of recipients, and return a list that contains only those
** recipients that are defined as mailing lists.
*/

static char *do_checkmailinglists(struct rfc822a *a,
                  struct rfc2045_mkreplyinfo *,
                  char *);

static char *mlcheck(struct rfc2045_mkreplyinfo *ri, const char *hdr)
{
    struct rfc822t *t;
    struct rfc822a *a;

    char *mlcopy;
    char *p;

    t=rfc822t_alloc_new(hdr, NULL, NULL);

    if (!t)
        return (0);

    a=rfc822a_alloc(t);

    if (!a)
    {
        rfc822t_free(t);
        return (0);
    }

    mlcopy=strdup(ri->mailinglists ? ri->mailinglists:"");
    if (!mlcopy)
        p=0;
    else
    {
        p=do_checkmailinglists(a, ri, mlcopy);
        free(mlcopy);
    }

    rfc822a_free(a);
    rfc822t_free(t);
    return (p);
}

static char *do_checkmailinglists(struct rfc822a *a,
                  struct rfc2045_mkreplyinfo *ri,
                  char *mlbuffer)
{
    int i;

    for (i=0; i<a->naddrs; i++)
    {
        char *p=rfc822_getaddr(a, i);
        char *q;

        if (!p)
            return (NULL);

        strcpy(mlbuffer, ri->mailinglists ? ri->mailinglists:"");

        for (q=mlbuffer; (q=strtok(q, "\n \t")) != NULL; q=NULL)
        {
            if (strcasecmp(p, q) == 0)
                break;
        }

        free(p);
        if (q == NULL)
        {
            rfc822_deladdr(a, i);
            --i;
        }
    }

    if (a->naddrs == 0)
        return (strdup(""));
    return (rfc822_getaddrs(a));
}
Command:
Quick Commands:
Upload:
[OK] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [OK]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.2786 seconds