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:25.65 GB of 70.42 GB (36.43%)
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/ webmail/ - drwxrwxrwx

Directory:
Viewing file:     newmsg_create.c (28.36 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 1998 - 2009 Double Precision, Inc.  See COPYING for
** distribution information.
*/


/*
*/
#include    "config.h"
#include    "cgi/cgi.h"
#include    "sqconfig.h"
#include    "sqwebmail.h"
#include    "auth.h"
#include    "maildir.h"
#include    "newmsg.h"
#include    "folder.h"
#include    "filter.h"
#include    "pref.h"
#include    "gpg.h"
#include    "addressbook.h"
#include    "maildir/maildirmisc.h"
#include    "rfc822/rfc822.h"
#include    "rfc2045/rfc2045.h"
#include    "rfc822/rfc2047.h"
#include    "rfc822/encode.h"
#include    "rfc822/rfc822hdr.h"
#include    "msg2html.h"
#include    "gpglib/gpglib.h"
#include    "http11/http11.h"
#include    "htmllibdir.h"
#include    "unicode/unicode.h"
#include    "courierauth.h"

#include    <stdlib.h>
#if HAVE_UNISTD_H
#include    <unistd.h>
#endif
#include    <ctype.h>
#include    <fcntl.h>

#define HASTEXTPLAIN(q) (rfc2045_searchcontenttype((q), "text/plain") != NULL)
/* Also in attachments.c */

extern const char *rfc822_mkdt(time_t);

extern const char *sqwebmail_content_charset;
extern const char *sqwebmail_content_language;

int newdraftfd;
extern const char *sqwebmail_mailboxid;

const char mimemsg[]="This is a MIME-formatted message.  If you see this text it means that your\nmail software cannot handle MIME-formatted messages.\n\n";

char *newmsg_createdraft_do(const char *, const char *, int);

/* Save message in a draft file */

char *newmsg_createdraft(const char *curdraft)
{
    if (curdraft && *curdraft)
    {
    char    *base=maildir_basename(curdraft);
    char    *filename=maildir_find(INBOX "." DRAFTS, base);

        if (filename)
        {
        char    *p=newmsg_createdraft_do(filename, cgi("message"), 0);

            free(filename);
            free(base);
            return (p);
        }
        free(base);
    }
    return (newmsg_createdraft_do(0, cgi("message"), 0));
}

static void create_draftheader_do(const char *hdrname, const char *p,
    int isrfc822addr);

static void create_draftheader(const char *hdrname, const char *p,
                   const char *q, int isrfc822addr)
{
    if (q && *q)    /* Add from address book */
    {
    char    *nick=cgi_multiple("nick", ",");
    char    *s;

        if (nick)
        {
            s=malloc(strlen(p)+strlen(nick)+2);

            if (s)
            {
                strcpy(s, p);
                if (*s && *nick)    strcat(s, ",");
                strcat(s, nick);
                create_draftheader_do(hdrname, s, isrfc822addr);
                free(s);
                free(nick);
                return;
            }
            free(nick);
        }

    }
    create_draftheader_do(hdrname, p, isrfc822addr);
}

#define    ISLWS(c)    ((c)=='\t' || (c)=='\r' || (c)=='\n' || (c)==' ')

static void header_wrap(const char *name, const char *hdr,
            char *outbuf, size_t *outcnt)
{
char    *pfix;
size_t    offset=strlen(name);

    *outcnt=0;
    pfix="";

    while (*hdr)
    {
    size_t i;
    size_t spc;

        for (spc=0, i=0; hdr[i]; i++)
        {
            if (i + offset >= 75 && spc)
            {
                    i = spc;
                offset = 0;
                break;
            }

            if (ISLWS(hdr[i]))
            {
                spc = i;
                while (ISLWS(hdr[i+1]))
                    ++i;
            }
        }

        if (outbuf)
        {
            strcpy(outbuf, pfix);
            outbuf += strlen(pfix);
        }
        *outcnt += strlen(pfix);

        if (outbuf)
        {
        size_t j;
            for (j=0; j < i; j++)
            {
                if (ISLWS(hdr[j]))
                {
                    *(outbuf++) = ' ';
                    while (ISLWS(hdr[j+1]))
                        ++j;
                }
                else
                    *(outbuf++) = hdr[j];
            }
        }
        *outcnt += i;
        pfix="\n  ";
        hdr += i;
        while (ISLWS(*hdr))
            ++hdr;
    }
    if (outbuf)
        *outbuf=0;
    ++*outcnt;
}
            
static void create_draftheader_do(const char *hdrname, const char *p,
    int isrfc822addr)
{
char    *s, *t;
size_t    l;

    if (!*p)    return;

    if (!isrfc822addr)
    {
        s=rfc2047_encode_str(p, sqwebmail_content_charset,
                     rfc2047_qp_allow_any);
    }
    else
    {
        s=rfc2047_encode_header_tobuf("to", p,
                          sqwebmail_content_charset);
    }

    header_wrap(hdrname, s, NULL, &l);
    if (l)
    {
        if (!(t=malloc(l))) enomem();
        header_wrap(hdrname, s, t, &l);
        if (*t)
        {
            free(s);
            s = t;
        }
        else
            free(t);
    }

    if (!s)
    {
        close(newdraftfd);
        enomem();
    }
    maildir_writemsgstr(newdraftfd, hdrname);
    maildir_writemsgstr(newdraftfd, s);
    maildir_writemsgstr(newdraftfd, "\n");
    free(s);
}

void newmsg_create_multipart(int newdraftfd, const char *charset,
            const char *multipart_boundary)
{
    maildir_writemsgstr(newdraftfd,
        "Mime-version: 1.0\n"
        "Content-Type: multipart/mixed; boundary=\"");
    maildir_writemsgstr(newdraftfd, multipart_boundary);
    maildir_writemsgstr(newdraftfd, "\"; charset=\"");
    maildir_writemsgstr(newdraftfd, charset);
    maildir_writemsgstr(newdraftfd, 
                    "\"\n\n");

    maildir_writemsgstr(newdraftfd, mimemsg);
}


static char    *newmsg_multipart_boundary(FILE *, const char *);
static void newmsg_copy_attachments(struct rfc2045 *, FILE *, const char *);

void newmsg_copy_nonmime_headers(FILE *fp)
{
char    *header, *value;
char    *q;

    while ((header=maildir_readheader(fp, &value, 1)) != NULL)
    {
        if (strcmp(header, "mime-version") == 0 ||
            strncmp(header, "content-", 8) == 0)    continue;

        /* Fluff - capitalize header names */

        for (q=header; *q; q++)
        {
            for (*q=toupper(*q); *q; q++)
                if (*q == '-')    break;
            if (!*q)
                break;
        }

        maildir_writemsgstr(newdraftfd, header);
        maildir_writemsgstr(newdraftfd, ": ");
        maildir_writemsgstr(newdraftfd, value);
        maildir_writemsgstr(newdraftfd, "\n");
    }
}

void newmsg_copy_content_headers(FILE *fp)
{
char    *header, *value;
char    *q;

    while ((header=maildir_readheader(fp, &value, 1)) != NULL)
    {
        if (strncmp(header, "content-", 8)) continue;

        for (q=header; *q; q++)
        {
            for (*q=toupper(*q); *q; q++)
                if (*q == '-')    break;
            if (!*q)
                break;
        }

        maildir_writemsgstr(newdraftfd, header);
        maildir_writemsgstr(newdraftfd, ": ");
        maildir_writemsgstr(newdraftfd, value);
        maildir_writemsgstr(newdraftfd, "\n");
    }
}

void wrap_text_init(struct wrap_info *uw,
            const char *output_chset,
            void (*output_func)(const char *p, size_t l, void *arg),
            void *arg)
{
    memset(uw, 0, sizeof(*uw));
    uw->output_func=output_func;
    uw->output_chset=output_chset;
    uw->arg=arg;
}

static void do_save_u_line(struct wrap_info *uw,
               const unicode_char *uc,
               size_t ucsize,
               int flowed)
{
    char *cbuf;
    size_t csize;

    libmail_u_convert_handle_t h=
        libmail_u_convert_fromu_init(uw->output_chset,
                         &cbuf,
                         &csize,
                         0);

    if (h)
    {
        if (ucsize)
        {
            if (uc[0] == ' ')
                libmail_u_convert_uc(h, uc, 1);
            /* Space stuff */

            libmail_u_convert_uc(h, uc, ucsize);
        }
        if (flowed)
        {
            unicode_char spc=' ';
            libmail_u_convert_uc(h, &spc, 1);
        }

        {
            unicode_char nl='\n';
            libmail_u_convert_uc(h, &nl, 1);
        }

        if (libmail_u_convert_deinit(h, NULL))
            cbuf=NULL;
    }
    else
        cbuf=NULL;

    if (cbuf)
    {
        (*uw->output_func)(cbuf, csize, uw->arg);
        free(cbuf);
    }
}

static void flush_line(struct wrap_info *uw, int flowed)
{
    do_save_u_line(uw, uw->uc + uw->line_start,
               uw->word_start - uw->line_start, flowed);

    uw->line_start=uw->word_start;
    uw->line_width=0;
}

static void add_word(struct wrap_info *uw)
{
    if (uw->line_start < uw->word_start &&
        uw->line_width + uw->word_width > MYLINESIZE)
        flush_line(uw, 1);

    uw->line_width += uw->word_width;

    uw->word_start=uw->cur_index;
    uw->word_width=0;
}

static int do_save_u_process_lb(int type, void *arg)
{
    struct wrap_info *uw=(struct wrap_info *)arg;

    if (uw->cur_index >= uw->ucsize)
        enomem();

    if (type != UNICODE_LB_NONE)
    {
        add_word(uw);
        if (type == UNICODE_LB_MANDATORY)
            flush_line(uw, 0);
    }


    if (uw->word_width >= MYLINESIZE &&
        uw->cur_index > 0 &&
        unicode_grapheme_break(uw->uc[uw->cur_index-1],
                   uw->uc[uw->cur_index]))
        add_word(uw);

    uw->word_width += unicode_wcwidth(uw->uc[uw->cur_index]);
    ++uw->cur_index;
    return 0;
}

static void do_wrap_u_line(struct wrap_info *uw,
               const unicode_char *uc,
               size_t ucsize)
{
    unicode_lb_info_t lb;

    while (ucsize && uc[ucsize-1] == ' ')
        --ucsize;

    uw->uc=uc;
    uw->ucsize=ucsize;
    uw->cur_index=0;
    uw->word_start=0;
    uw->word_width=0;

    uw->line_start=0;
    uw->line_width=0;
    if ((lb=unicode_lb_init(do_save_u_process_lb, uw)) != NULL)
    {
        unicode_lb_set_opts(lb,
                    UNICODE_LB_OPT_PRBREAK
                    | UNICODE_LB_OPT_SYBREAK);
        unicode_lb_next_cnt(lb, uc, ucsize);
        unicode_lb_end(lb);
        add_word(uw);
        flush_line(uw, 0);
    }
}

static void save_textplain(const char *p, size_t l, void *dummy)
{
    maildir_writemsg(newdraftfd, p, l);
}

void wrap_text(struct wrap_info *uw,
           const char *newmsg,
           size_t newmsg_size)
{
    size_t i=0, j;

    while (i < newmsg_size)
    {
        unicode_char *uc;
        size_t ucsize;
        libmail_u_convert_handle_t h;

        j=i;

        while (i<newmsg_size && newmsg[i] != '\n')
            ++i;

        h=libmail_u_convert_tou_init(sqwebmail_content_charset,
                         &uc, &ucsize, 0);

        if (h)
        {
            libmail_u_convert(h, newmsg+j, i-j);

            if (libmail_u_convert_deinit(h, NULL))
                uc=NULL;
        }
        else
        {
            uc=NULL;
        }

        if (uc)
        {
            size_t i, j;

            /* Get rid of any CRs that sneak in */

            for (i=j=0; i<ucsize; ++i)
            {
                if (uc[i] == '\r')
                    continue;

                uc[j]=uc[i];
                ++j;
            }

            if (j && *uc == '>')
                do_save_u_line(uw, uc, j, 0);
            else
                do_wrap_u_line(uw, uc, j);

            free(uc);
        }

        if (i < newmsg_size)
            ++i;
    }
}

static void convert_text2html(const char *p, size_t l, void *arg)
{
    struct msg2html_textplain_info *info=
        (struct msg2html_textplain_info *)arg;

    msg2html_textplain(info, p, l);
}

static char *mkurl(const char *url, void *dummy)
{
    char *buf=malloc(strlen(url)*2+100);

    if (!buf)
        return NULL;

    /* msg2html guarantees that the characters in url are "safe" */

    sprintf(buf, "<a href=\"%s\">%s</a>", url, url);
    return buf;
}

char *newmsg_createdraft_do(const char *curdraft, const char *newmsg,
    int keepheader)
{
char    *draftfilename;
FILE    *fp=0;
char    *multipart_boundary;
const char *content_type;
const char *content_transfer_encoding;
const char *charset;
unsigned long prev_size=0;
off_t    transferencodingpos;
off_t    transferencoding2pos;
int is_newevent=strcmp(cgi("form"), "newevent") == 0;
struct    rfc2045    *rfcp;
int has_attachments=0;
size_t newmsg_size;
char *sig, *footer;

/*
** Trim extra newlines.
*/
    newmsg_size=strlen(newmsg);

    while (newmsg_size && newmsg[newmsg_size-1] == '\n')
        --newmsg_size;

/* We're on the 'new event' screen */

     if (curdraft)    /* Reuse a draft filename */
        newdraftfd=maildir_recreatemsg(INBOX "." DRAFTS, curdraft, &draftfilename);
    else
        newdraftfd=maildir_createmsg(INBOX "." DRAFTS, 0, &draftfilename);
    if (newdraftfd < 0)    enomem();

    pref_wikifmt=0;
    if (strcmp(cgi("textformat"), "wiki") == 0)
        pref_wikifmt=1;
    pref_update();

    fp=NULL;
    if (curdraft)
    {
    int    x=maildir_safeopen(curdraft, O_RDONLY, 0);

        if (x >= 0)
            if ((fp=fdopen(x, "r")) == 0)
                close(x);
    }

    if (fp)
    {
    char    *header, *value;
    struct    stat    stat_buf;

        if (fstat(fileno(fp), &stat_buf))
        {
            fclose(fp);
            enomem();
        }
        prev_size=stat_buf.st_size;

        while ((header=maildir_readheader(fp, &value, 1)) != NULL)
        {
            if (keepheader == NEWMSG_SQISPELL)
            {
                if (strcasecmp(header, "mime-version") == 0 ||
                    strncasecmp(header, "content-", 8) == 0)
                    continue;
            }
            else if (keepheader == NEWMSG_PCP)
            {
                if (strcasecmp(header, "mime-version") == 0 ||
                    strncasecmp(header, "content-", 8) == 0 ||
                    strcasecmp(header, "date") == 0 ||
                    strcasecmp(header, "from") == 0 ||
                    strcasecmp(header, "subject") == 0)
                    continue;
            }
            else
            {
                if (strcmp(header, "in-reply-to") &&
                    strcmp(header, "references") &&
                    strncmp(header, "x-", 2))    continue;
                /* Do not discard these headers */
            }

            if (strcasecmp(header, "x-sqwebmail-wikifmt") == 0)
                continue;

            maildir_writemsgstr(newdraftfd, header);
            maildir_writemsgstr(newdraftfd, ": ");
            maildir_writemsgstr(newdraftfd, value);
            maildir_writemsgstr(newdraftfd, "\n");
        }
    }
    else if (is_newevent)
        maildir_writemsgstr(newdraftfd, "X-Event: 1\n");

    if (!keepheader
        || keepheader == NEWMSG_PCP)
    /* Coming back from msg edit, set headers */
    {
    const    char *p=cgi("headerfrom");

        if (!*p)    p=pref_from;
        if (!p || !*p || auth_getoptionenvint("wbnochangingfrom"))
            p=login_fromhdr();

        create_draftheader("From: ", p, 0, 1);

        if (!pref_from || strcmp(p, pref_from))
            pref_setfrom(p);

/* sam ????
    create_draftheader("In-Reply-To: ", cgi("headerin-reply-to"));
*/
        if (!is_newevent)
        {
#if 0
            {
                FILE *fp;
                fp=fopen("/tmp/pid", "w");
                fprintf(fp, "%d", getpid());
                fclose(fp);
                sleep(10);
            }
#endif

            create_draftheader("To: ", cgi("headerto"),
                       cgi("addressbook_to"), 1);
            create_draftheader("Cc: ", cgi("headercc"),
                       cgi("addressbook_cc"), 1);
            create_draftheader("Bcc: ", cgi("headerbcc"),
                       cgi("addressbook_bcc"), 1);
            create_draftheader("Reply-To: ", cgi("headerreply-to"), 0, 1);
        }
    }

    if (pref_wikifmt)
        create_draftheader("x-sqwebmail-wikifmt: ", "1", 0, 0);

    if (!keepheader || keepheader == NEWMSG_PCP)
    {
    time_t    t;

        create_draftheader("Subject: ", cgi("headersubject"), 0, 0);

        time(&t);
        create_draftheader("Date: ", rfc822_mkdate(t), 0, 0);
    }

    /* If the message has attachments, calculate multipart boundary */

    rfcp=NULL;

    if (fp)
    {
        rfcp=rfc2045_fromfp(fp);
        if (!rfcp)
        {
            close(newdraftfd);
            fclose(fp);
            enomem();
        }
    }

    multipart_boundary=newmsg_multipart_boundary(fp, newmsg);

    if (rfcp && rfcp->firstpart &&
        strcmp((rfc2045_mimeinfo(rfcp, &content_type,
                  &content_transfer_encoding, &charset),
            content_type), "multipart/mixed") == 0)
    {
        has_attachments=1;
        newmsg_create_multipart(newdraftfd,
            sqwebmail_content_charset, multipart_boundary);

        maildir_writemsgstr(newdraftfd, "--");
        maildir_writemsgstr(newdraftfd, multipart_boundary);
        maildir_writemsgstr(newdraftfd,"\n");
    }
    else
    {
        maildir_writemsgstr(newdraftfd, "Mime-Version: 1.0\n");
    }

    if (pref_wikifmt)
    {
        ++multipart_boundary[strlen(multipart_boundary)-1];

        maildir_writemsgstr(newdraftfd,
                    "Content-Type: multipart/alternative;"
                    " boundary=\"");
        maildir_writemsgstr(newdraftfd, multipart_boundary);
        maildir_writemsgstr(newdraftfd, "\"\n"
                    "\n"
                    "\n"
                    "--");
        maildir_writemsgstr(newdraftfd, multipart_boundary);
        maildir_writemsgstr(newdraftfd, "\n");
    }

    maildir_writemsgstr(newdraftfd,
                "Content-Type: text/plain; format=flowed; delsp=yes;"
                " charset=\"");
    maildir_writemsgstr(newdraftfd, sqwebmail_content_charset);
    maildir_writemsgstr(newdraftfd, "\"\n");

    maildir_writemsgstr(newdraftfd, "Content-Transfer-Encoding: ");
    transferencoding2pos=transferencodingpos=writebufpos;
    maildir_writemsgstr(newdraftfd, "7bit\n\n");

    /*    maildir_writemsgstr(newdraftfd, "\n"); */

    sig=pref_getsig();
    footer=pref_getfile(http11_open_langfile(get_templatedir(),
                         sqwebmail_content_language,
                         "footer"));

    while (newmsg_size &&
           (newmsg[newmsg_size-1] == '\r' ||
        newmsg[newmsg_size-1] == '\n'))
        --newmsg_size;

    {
        struct wrap_info uw;

        wrap_text_init(&uw, sqwebmail_content_charset,
                   save_textplain, NULL);

        wrap_text(&uw, newmsg, newmsg_size);

        if ((sig && *sig) || (footer && *footer))
        {
            static const unicode_char sig_line[]={'-', '-', ' '};

            do_save_u_line(&uw, sig_line, 0, 0);
            do_save_u_line(&uw, sig_line, 3, 0);
        }

        if (sig && *sig)
            wrap_text(&uw, sig, strlen(sig));

        if (footer && *footer)
        {
            do_save_u_line(&uw, NULL, 0, 0);
            maildir_writemsg(newdraftfd, footer, strlen(footer));
        }

    }

    if (pref_wikifmt)
    {
        struct msg2html_textplain_info *info;

        maildir_writemsgstr(newdraftfd, "\n"
                    "--");
        maildir_writemsgstr(newdraftfd, multipart_boundary);
        maildir_writemsgstr(newdraftfd, "\n"
                    "Content-Type: text/html; charset=\"");
        maildir_writemsgstr(newdraftfd, sqwebmail_content_charset);
        maildir_writemsgstr(newdraftfd, "\"\n"
                    "Content-Transfer-Encoding: ");
        transferencoding2pos=writebufpos;
        maildir_writemsgstr(newdraftfd, "7bit\n\n");

        info=msg2html_textplain_start(sqwebmail_content_charset,
                          sqwebmail_content_charset,
                          1,
                          1,
                          0,
                          mkurl, NULL,
                          NULL,
                          NULL,
                          1,
                          save_textplain,
                          NULL);

        if (info)
        {
            struct wrap_info uw;

            wrap_text_init(&uw, sqwebmail_content_charset,
                       convert_text2html, info);

            wrap_text(&uw, newmsg, newmsg_size);
            msg2html_textplain_end(info);
        }

        if ((sig && *sig) || (footer && *footer))
            save_textplain("<hr />\n", 7, NULL);

        if (sig && *sig)
        {

            info=msg2html_textplain_start(sqwebmail_content_charset,
                              sqwebmail_content_charset,
                              1,
                              1,
                              0,
                              mkurl, NULL,
                              NULL,
                              NULL,
                              1,
                              save_textplain,
                              NULL);

            if (info)
            {
                struct wrap_info uw;

                wrap_text_init(&uw, sqwebmail_content_charset,
                           convert_text2html, info);

                wrap_text(&uw, sig, strlen(sig));
                msg2html_textplain_end(info);
            }
        }

        if (footer && *footer)
        {
            save_textplain("<br />\n", 7, NULL);

            info=msg2html_textplain_start(sqwebmail_content_charset,
                              sqwebmail_content_charset,
                              1,
                              1,
                              0,
                              mkurl, NULL,
                              NULL,
                              NULL,
                              1,
                              save_textplain,
                              NULL);

            if (info)
            {
                msg2html_textplain(info, footer,
                           strlen(footer));
                msg2html_textplain_end(info);
            }
        }

        maildir_writemsgstr(newdraftfd, "\n"
                    "--");
        maildir_writemsgstr(newdraftfd, multipart_boundary);
        maildir_writemsgstr(newdraftfd, "--\n");
        --multipart_boundary[strlen(multipart_boundary)-1];

    }

    if (sig)
        free(sig);

    if (footer)
        free(footer);

    if ( multipart_boundary && rfcp && has_attachments)
    {
        newmsg_copy_attachments(rfcp, fp, multipart_boundary);
        maildir_writemsgstr(newdraftfd, "\n--");
        maildir_writemsgstr(newdraftfd, multipart_boundary);
        maildir_writemsgstr(newdraftfd, "--\n");
        free(multipart_boundary);
    }
    if (fp)    fclose(fp);
    if (rfcp)
        rfc2045_free(rfcp);

    if ( maildir_writemsg_flush(newdraftfd) == 0 && writebuf8bit)
    {
        if (lseek(newdraftfd, transferencodingpos, SEEK_SET) < 0 ||
            write(newdraftfd, "8", 1) != 1 ||
            lseek(newdraftfd, transferencoding2pos, SEEK_SET) < 0 ||
            write(newdraftfd, "8", 1) != 1)
        {
            close(newdraftfd);
            enomem();
        }
    }

    if ( maildir_closemsg(newdraftfd, INBOX "." DRAFTS, draftfilename, -1, prev_size))
        cgi_put("error", "quota");

    return(draftfilename);
}

static void sentmsg_copy(FILE *f, struct rfc2045 *p)
{
    off_t start_pos, end_pos, start_body;
    char buf[BUFSIZ];
    int n;
    off_t   dummy;

        rfc2045_mimepos(p, &start_pos, &end_pos, &start_body, &dummy, &dummy);
        if (fseek(f, start_pos, SEEK_SET) == -1)
        {
                fclose(f);
                close(newdraftfd);
                enomem();
        }

        while (start_pos < end_pos)
        {
        int     cnt=sizeof(buf);

                if (cnt > end_pos - start_pos)
                        cnt=end_pos - start_pos;

                if ((n=fread(buf, 1, cnt, f)) <= 0)
                {
                        fclose(f);      
                        close(newdraftfd);
                        enomem();
                }

                maildir_writemsg(newdraftfd, buf, n);
                start_pos += n;
        }
}


/* Create message in the sent folder */

static void header_uc(char *h)
{
    while (*h)
    {
        *h=toupper( (int)(unsigned char) *h);
        while (*h)
        {
            if (*h++ == '-')    break;
        }
    }
}

struct lookup_buffers {
    struct lookup_buffers *next;
    char *buf;
    char *buf2;
    } ;

static int lookup_addressbook_do(const char *header, const char *value,
    struct lookup_buffers **lookup_buffer_list)
{
    struct    rfc822t *t;
    struct    rfc822a *a;
    int    i;
    char    *newbuf;
    struct lookup_buffers *ptr;
    int    expanded=0;

    t=rfc822t_alloc_new(value, NULL, NULL);
    if (!t)    enomem();
    a=rfc822a_alloc(t);
    if (!a)
    {
        rfc822t_free(t);
        enomem();
    }

    for (i=0; i<a->naddrs; i++)
    {
        char    *p;
        char    *s;
        const    char *q;
        struct lookup_buffers *r;

        if (a->addrs[i].tokens == 0)
            continue;
        if (a->addrs[i].name)
            continue;    /* Can't be a nickname */

        p=rfc822_getaddr(a, i);
        if (!p)
        {
            rfc822a_free(a);
            rfc822t_free(t);
            free(p);
            return (-1);
        }

        for (ptr= *lookup_buffer_list; ptr; ptr=ptr->next)
            if (strcmp(ptr->buf2, p) == 0)
                break;

        if (ptr)    /* Address book loop */
        {
        int    j;

            for (j=i+1; j<a->naddrs; j++)
                a->addrs[j-1]=a->addrs[j];
            --a->naddrs;
            --i;
            free(p);
            continue;
        }

        s=rfc822_display_addr_str_tobuf(p, "utf-8");

        if (s == NULL || (q=ab_find(s)) == 0)
        {
            if (s)
                free(s);
            free(p);
            continue;
        }
        free(s);

        r=malloc(sizeof(struct lookup_buffers));
        if (r)    r->buf=r->buf2=0;

        if (!r || !(r->buf=strdup(q)) || !(r->buf2=strdup(p)))
        {
            free(p);
            if (r && r->buf)    free(r->buf);
            if (r)    free(r);
            rfc822a_free(a);
            rfc822t_free(t);
            return (-1);
        }
        free(p);
        r->next= *lookup_buffer_list;
        *lookup_buffer_list=r;
        a->addrs[i].tokens->next=0;
        a->addrs[i].tokens->token=0;
        a->addrs[i].tokens->ptr=r->buf;
        a->addrs[i].tokens->len=strlen(r->buf);
        expanded=1;
    }

    newbuf=rfc822_getaddrs_wrap(a, 70);
    rfc822a_free(a);
    rfc822t_free(t);
    if (!newbuf)    return (-1);

    if (expanded)    /* Look through the address book again */
    {
    int    rc=lookup_addressbook_do(header, newbuf, lookup_buffer_list);

        free(newbuf);
        return (rc);
    }

    create_draftheader_do(header, newbuf, 1);
    free(newbuf);
    return (0);
}

static void lookup_addressbook(const char *header, const char *value)
{
    struct lookup_buffers *lookup_buffer_list=0;
    int    rc;
    char *header_cpy;
    char *value_cpy;
    /*
    ** header & value may be pointing to buffer allocated by
    ** maildir_readheader.
    ** lookup_addressbook_do may call it again.
    */

    header_cpy=strdup(header);
    if (!header_cpy)
        enomem();

    value_cpy=strdup(value);
    if (!value_cpy)
    {
        free(header_cpy);
        enomem();
    }

    rc=lookup_addressbook_do(header_cpy, value_cpy, &lookup_buffer_list);
    free(header_cpy);

    while (lookup_buffer_list)
    {
    struct lookup_buffers *p=lookup_buffer_list;

        lookup_buffer_list=p->next;
        free(p->buf);
        free(p->buf2);
        free(p);
    }
    if (rc)    enomem();
}

char *newmsg_createsentmsg(const char *draftname, int *isgpgerr)
{
char    *filename=maildir_find(INBOX "." DRAFTS, draftname);
FILE    *fp;
char    *sentname;
char    *header, *value;
struct    rfc2045 *rfcp;
int    x;

    *isgpgerr=0;
 
    if (!filename)    return (0);

    fp=0;

    x=maildir_safeopen(filename, O_RDONLY, 0);
    if (x >= 0)
        if ((fp=fdopen(x, "r")) == 0)
            close(x);

    if (fp == 0)
    {
        free(filename);
        enomem();
    }

    rfcp=rfc2045_fromfp(fp);
    if (!rfcp || fseek(fp, 0L, SEEK_SET) < 0)
    {
        fclose(fp);
        close(newdraftfd);
        enomem();
    }

    newdraftfd=maildir_createmsg(INBOX "." SENT, 0, &sentname);
    if (newdraftfd < 0)
    {
        rfc2045_free(rfcp);
        free(filename);
        fclose(fp);
        enomem();
    }
    /* First, copy all headers except X- headers */

    while ((header=maildir_readheader(fp, &value, 1)) != 0)
    {
        if (strncmp(header, "x-", 2) == 0)    continue;
        header_uc(header);
        if (rfc822hdr_namecmp(header, "To") == 0)
        {
            lookup_addressbook("To: ", value);
            continue;
        }

        if (rfc822hdr_namecmp(header, "Cc") == 0)
        {
            lookup_addressbook("Cc: ", value);
            continue;
        }

        if (rfc822hdr_namecmp(header, "Bcc") == 0)
        {
            lookup_addressbook("Bcc: ", value);
            continue;
        }

        maildir_writemsgstr(newdraftfd, header);
        maildir_writemsgstr(newdraftfd, ": ");
        maildir_writemsgstr(newdraftfd, value);
        maildir_writemsgstr(newdraftfd, "\n");
    }
    if (auth_getoptionenvint("wbusexsender"))
    {
        maildir_writemsgstr(newdraftfd, "X-Sender: ");
        maildir_writemsgstr(newdraftfd, login_returnaddr());
        maildir_writemsgstr(newdraftfd, "\n");
    }

    maildir_writemsgstr(newdraftfd, "\n");

    {
        off_t start_pos, end_pos, start_body;
        char buf[BUFSIZ];
        int n;
        off_t   dummy;
        
        rfc2045_mimepos(rfcp, &start_pos, &end_pos, &start_body,
                &dummy, &dummy);

        if (fseek(fp, start_body, SEEK_SET) == -1)
        {
            fclose(fp);
            close(newdraftfd);
            enomem();
        }

        while (start_body < end_pos)
        {
            int     cnt=sizeof(buf);

            if (cnt > end_pos - start_pos)
                cnt=end_pos - start_pos;

            if ((n=fread(buf, 1, cnt, fp)) <= 0)
            {
                fclose(fp);      
                close(newdraftfd);
                enomem();
            }

            maildir_writemsg(newdraftfd, buf, n);
            start_body += n;
        }
    }


    if ( maildir_writemsg_flush(newdraftfd))
    {
        free(sentname);
        return (0);
    }

#if 0
    if (writebuf8bit)
    {
        if (lseek(newdraftfd, transferencodingpos, SEEK_SET) < 0 ||
            write(newdraftfd, "8", 1) != 1)
        {
            free(sentname);
            return (0);
        }
    }
#endif

    if ( maildir_writemsg_flush(newdraftfd))
    {
        maildir_closemsg(newdraftfd, INBOX "." SENT, sentname, 0, 0);
        free(sentname);
        return (0);
    }

    if (libmail_gpg_has_gpg(GPGDIR) == 0)
    {
        char dosign= *cgi("sign");
        char doencrypt= *cgi("encrypt");
        const char *signkey= cgi("signkey");
        char *encryptkeys=cgi_multiple("encryptkey", " ");

        if (!encryptkeys)
            enomem();

        if (gpgbadarg(encryptkeys) || !*encryptkeys)
        {
            free(encryptkeys);
            encryptkeys=0;
        }

        if (gpgbadarg(signkey) || !*signkey)
        {
            signkey=0;
        }

        if (!encryptkeys)
            doencrypt=0;

        if (!signkey)
            dosign=0;

        if (lseek(newdraftfd, 0L, SEEK_SET) < 0)
        {
            maildir_closemsg(newdraftfd, INBOX "." SENT,
                     sentname, 0, 0);
            free(sentname);
            return (0);
        }

        if (!dosign)
            signkey=0;
        if (!doencrypt)
            encryptkeys=0;

        if (dosign || doencrypt)
        {
            /*
            ** What we do is create another draft, then substitute
            ** it for newdraftfd/sentname.  Sneaky.
            */

            char *newnewsentname;
            int newnewdraftfd=maildir_createmsg(INBOX "." SENT, 0,
                                &newnewsentname);

            if (newnewdraftfd < 0)
            {
                maildir_closemsg(newdraftfd, INBOX "." SENT,
                         sentname, 0, 0);
                free(sentname);
                free(encryptkeys);
                return (0);
            }

            if (gpgdomsg(newdraftfd, newnewdraftfd,
                     signkey, encryptkeys))
            {
                maildir_closemsg(newnewdraftfd, INBOX "." SENT,
                         newnewsentname, 0, 0);
                free(newnewsentname);
                maildir_closemsg(newdraftfd, INBOX "." SENT,
                         sentname, 0, 0);
                free(sentname);
                free(encryptkeys);
                *isgpgerr=1;
                return (0);
            }

            maildir_closemsg(newdraftfd, INBOX "." SENT, sentname, 0, 0);
            free(sentname);
            sentname=newnewsentname;
            newdraftfd=newnewdraftfd;

        }
        free(encryptkeys);
    }

    if ( maildir_closemsg(newdraftfd, INBOX "." SENT, sentname, 1, 0))
    {
        free(sentname);
        return (0);
    }
    return (sentname);
}

/* ---------------------------------------------------------------------- */

/* Create a potential multipart boundary separator tag */

char *multipart_boundary_create()
{
char    pidbuf[MAXLONGSIZE];
char    timebuf[MAXLONGSIZE];
time_t    t;
char    cntbuf[MAXLONGSIZE];
static unsigned long cnt=0;
char    *p;

    sprintf(pidbuf, "%lu", (unsigned long)getpid());
    time(&t);
    sprintf(timebuf, "%lu", (unsigned long)t);
    sprintf(cntbuf, "%lu", cnt++);
    p=malloc(strlen(pidbuf)+strlen(timebuf) +strlen(cntbuf)+20);
    sprintf(p, "=_%s_%s_%s_000", cntbuf, pidbuf, timebuf);
    return (p);
}

/* Search for the boundary tag in a string buffer - this is the new message
** we're creating.  We should really look for the tag at the beginning of the
** line, however, the text is not yet linewrapped, besides, why make your
** life hard?
*/

int multipart_boundary_checks(const char *boundary, const char *msg)
{
size_t    boundarylen=strlen(boundary);

    while (*msg)
    {
        if (msg[0] == '-' && msg[1] == '-' && msg[2] != '-' &&
            strncasecmp(msg+2, boundary, boundarylen) == 0)
                return (-1);
        ++msg;
    }
    return (0);
}

/* Again, just look for it at the beginning of the line -- why make your
** life hard? */

int multipart_boundary_checkf(const char *boundary, FILE *f)
{
size_t    boundarylen=strlen(boundary);
const char *line;

    if (fseek(f, 0L, SEEK_SET) == -1)
    {
        fclose(f);
        close(newdraftfd);
        enomem();
    }

    while ((line=maildir_readline(f)) != 0)
        if (line[0] == '-' && line[1] == '-' &&
            strncasecmp(line+2, boundary, boundarylen) == 0)
                return (-1);
    return (0);
}

/* ---------------------------------------------------------------------- */

/* Copy existing attachments into the new draft message */

/* multipart_boundary - determine if current draft has attachments */

static char    *newmsg_multipart_boundary(FILE *f, const char *msg)
{
    char    *p=0;

    do
    {
        if (p)    free(p);
        p=multipart_boundary_create();
    } while (multipart_boundary_checks(p, msg)
         || (f && multipart_boundary_checkf(p, f)));
    return (p);
}

static void    newmsg_copy_attachments(struct rfc2045 *rfcp,
                    FILE *f, const char *boundary)
{
struct    rfc2045 *p;
int    foundtextplain=0;

    for (p=rfcp->firstpart; p; p=p->next)
    {
        if (p->isdummy)    continue;
        if (!foundtextplain && HASTEXTPLAIN(p))
        {    /* Previous version of this message */

            foundtextplain=1;
            continue;
        }
        maildir_writemsgstr(newdraftfd, "\n--");
        maildir_writemsgstr(newdraftfd, boundary);
        maildir_writemsgstr(newdraftfd, "\n");
        sentmsg_copy(f, p);    /* Reuse some code */
    }
}
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.7741 seconds