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:24.51 GB of 70.42 GB (34.8%)
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/ maildrop-2.2.0/ maildrop/ - drwxr-xr-x

Directory:
Viewing file:     reformail.C (28.78 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
** Copyright 1998 - 2008 Double Precision, Inc.
** See COPYING for distribution information.
*/

#include    "config.h"

#include    <stdio.h>
#include    <iostream>
#include    <iomanip>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    <signal.h>
#include    <pwd.h>

#if    HAVE_LOCALE_H
#include    <locale.h>
#endif

#if HAVE_UNISTD_H
#include    <unistd.h>
#endif
#if HAVE_FCNTL_H
#include    <fcntl.h>
#endif
#include    "mytime.h"
#include    <sys/types.h>
#include    "mywait.h"
#if HAVE_SYS_FILE_H
#include    <sys/file.h>
#endif
#include    "rfc822.h"
#include    "buffer.h"
#include    "liblock/config.h"
#include    "liblock/liblock.h"

#if    HAS_GETHOSTNAME
#else
extern "C" int gethostname(const char *, size_t);
#endif

static const char rcsid[]="$Id: reformail.C,v 1.21 2008/07/26 12:01:56 mrsam Exp $";

static int inbody=0, addcrs=0, catenate=0, keep_body=0, autoreply_envelope=1;
static const char *(*autoreply_ptr)(), *(*append_more_headers)();
static const char *autoreply_pfix="> ";
static const char *autoreply_opts=0;
Buffer  autoreply_salutation;
Buffer    salutation_template;
Buffer    autoreply_buf;
Buffer    sender_name;
Buffer    sender_addr;
Buffer    optx, optX, opta, optA, opti, optI, optu, optU, optubuf, optUbuf, optR;
const char *autoreply_buf_ptr;

Buffer from_line;
Buffer add_from_filter_buf;
const char *add_from_filter_buf_ptr;
const char *cache_maxlen="", *cache_name="";

static const char *( *from_filter)();
Buffer    current_line;

void outofmem()
{
    std::cerr << "reformail: Out of memory." << std::endl;
    exit(1);
}

void help()
{
    std::cerr << "reformail: Invalid arguments." << std::endl;
    exit(1);
}

// Return next line from standard input.  Trailing CRs are stripped

const char *NextLine()
{
static Buffer buf;
int    c;

    buf.reset();
    while ((c=std::cin.get()) >= 0 && c != '\n')
        buf.push(c);
    if (c < 0 && buf.Length() == 0)    return (0);
    if (buf.Length())    // Strip CRs
    {
        c=buf.pop();
        if (c != '\r')    buf.push(c);
    }
    buf.push('\n');
    buf.push('\0');
    return (buf);
}

// from_filter is the initial filtering done on the message.
// from_filter adds or subtracts "From " quoting from the message.
// from_filter returns the next line from the message, after filtering.
// The line is always terminated by a newline character.
// When the header is being read, multiline headers are silently
// concatenated into a single return from from_filter() (separated by
// newlines, of course.
//
// from_filter is initialized to either from_filter(), add_from_filter()
// and rem_from_filter() respectively, to cause either addition, removal of,
// or no change to from quoting.  The pointer is automatically updated.
//
// Also, the from_filter silently discards empty lines at the beginning of
// the message.

// DO NOT CHANGE FROM QUOTING.

const char *no_from_filter_header();

const char *no_from_filter()
{
const    char *p;

    while ((p=NextLine()) && *p == '\n')
        ;
    if (!p)    return (0);

    current_line=p;
    return ( no_from_filter_header() );
}

const char *read_blank();

const char *no_from_filter_header()
{
const    char *p;

static Buffer buf;

    from_filter= &no_from_filter_header;

    while ((p=NextLine()) && *p && *p != '\n' && isspace((unsigned char)*p))
        current_line += p;

    buf=current_line;
    buf+='\0';
    if (!p || *p == '\n')
    {
        from_filter= &read_blank;
        return (buf);
    }
    current_line=p;
    return (buf);
}

const char *read_blank()
{
    from_filter= &NextLine;
    return ("\n");
}

//////////////////////////////////////////////////////////////////////////
//
//  Add 'From ' quoting.  All headers are read into add_from_filter_buf,
//  and a suitable return address is located.  The 'From ' line is
//  generated, and return.  Subsequent calls fetch one header at a
//  time from add_from_filter_buf, then resume reading the body of the
//  message.
//
//////////////////////////////////////////////////////////////////////////

static void add_from_line(char c, void *p)
{
    p=p;
    from_line.push(c);
}

const char *add_from_filter_header();
const char *add_from_filter()
{
const    char *p;

    while ((p=NextLine()) && *p == '\n')
        ;
    if (!p)    return (0);

    current_line=p;
    if (strncmp(p, "From ", 5) == 0)
        return ( no_from_filter_header() );
    add_from_filter_buf.reset();
    while (p && *p != '\n')
    {
        add_from_filter_buf += p;
        p=NextLine();
    }

    add_from_filter_buf += '\0';

static Buffer    return_path;
static Buffer    from_header;

    return_path.reset();
    from_header.reset();

    for (p=add_from_filter_buf; *p; )
    {
    Buffer    header;

        while (*p && *p != ':' && *p != '\n')
        {
        int    c= (unsigned char)*p++;

            c=tolower(c);
            header.push(c);
        }
        for (;;)
        {
            while (*p && *p != '\n')
            {
                header.push(*p);
                p++;
            }
            if (!*p)    break;
            ++p;
            header.push('\n');
            if (!*p || !isspace((unsigned char)*p))    break;
        }
        header.push('\0');
        if (strncmp(header, "return-path:", 12) == 0 ||
            strncmp(header, ">return-path:", 13) == 0 ||
            strncmp(header, "errors-to:", 10) == 0 ||
            strncmp(header, ">errors-to:", 11) == 0)
        {
            for (p=header; *p != ':'; p++)
                ;
            return_path=p;
        }

        if (strncmp(header, "from:", 5) == 0)
            from_header=(const char *)header + 5;
    }
    if (return_path.Length() == 0)    return_path=from_header;
    return_path += '\0';

struct rfc822t *rfc=rfc822t_alloc_new( (const char *)return_path, NULL, NULL);

    if (!rfc)    outofmem();

struct rfc822a *rfca=rfc822a_alloc( rfc);

    if (!rfca)    outofmem();

    rfc822_addrlist(rfca, &add_from_line, NULL);
    rfc822a_free(rfca);
    rfc822t_free(rfc);

    from_line.push('\0');
    from_header.reset();
    for (p=from_line; *p && *p != '\n'; p++)
        from_header.push(*p);
    if (from_header.Length() == 0)    from_header="root";
    return_path="From ";
    return_path += from_header;
    return_path.push(' ');
time_t    t;

    time(&t);
    p=ctime(&t);
    while (*p && *p != '\n')
    {
        return_path.push(*p);
        p++;
    }
    return_path += '\n';
    return_path += '\0';
    from_filter=add_from_filter_header;
    add_from_filter_buf_ptr=add_from_filter_buf;
    return (return_path);
}

const char *add_from_filter_body();

const char *add_from_filter_header()
{
static Buffer buf;

    buf.reset();
    
    if (*add_from_filter_buf_ptr == '\0')
    {
        from_filter= &add_from_filter_body;
        return ("\n");
    }

    do
    {
        while (*add_from_filter_buf_ptr)
        {
            buf.push ( (unsigned char)*add_from_filter_buf_ptr );
            if ( *add_from_filter_buf_ptr++ == '\n')    break;
        }
    } while ( *add_from_filter_buf_ptr && *add_from_filter_buf_ptr != '\n'
        && isspace( (unsigned char)*add_from_filter_buf_ptr ));
    buf += '\0';
    return (buf);
}

const char *add_from_filter_body()
{
const char *p=NextLine();

    if (!p)    return (p);

const char *q;

    for (q=p; *q == '>'; q++)
        ;
    if (strncmp(q, "From ", 5))    return (p);

static Buffer add_from_buf;

    add_from_buf=">";
    add_from_buf += p;
    add_from_buf += '\0';
    return (add_from_buf);
}

////////////////////////////////////////////////////////////////////////////
//
// Strip From quoting.
//
////////////////////////////////////////////////////////////////////////////

const char *rem_from_filter_header();

const char *(*rem_from_filter_header_ptr)();

const char *rem_from_filter()
{
const    char *p;

    while ((p=NextLine()) && *p == '\n')
        ;
    if (!p)    return (0);

    if (strncmp(p, "From ", 5))
    {
        current_line=p;
        return ( no_from_filter_header() );
    }
    p=NextLine();
    if (!p)    return (p);
    current_line=p;
    rem_from_filter_header_ptr= &no_from_filter_header;
    return ( rem_from_filter_header() );
}

const char *rem_from_filter_body();
const char *rem_from_filter_header()
{
const char *p=(*rem_from_filter_header_ptr)();

    rem_from_filter_header_ptr=from_filter;
    from_filter=rem_from_filter_header;
    if (!p || *p == '\n')
    {
        from_filter=&rem_from_filter_body;
        p="\n";
    }
    return (p);
}

const char *rem_from_filter_body()
{
const char *p=NextLine();

    if (!p)    return (p);

    if (*p == '>')
    {
    const char *q;

        for (q=p; *q == '>'; q++)
            ;
        if (strncmp(q, "From ", 5) == 0)    ++p;
    }
    return (p);
}

const char *no_autoreply()
{
    return (*from_filter)();
}

static const char *HostName()
{
static char hostname_buf[256];

    hostname_buf[0]=0;
    hostname_buf[sizeof(hostname_buf)-1]=0;
    gethostname(hostname_buf, sizeof(hostname_buf)-1);
    return (hostname_buf);
}

static void add_sender_name(char c, void *p)
{
    p=p;
    if (c == '\n')    c=' ';
    sender_name.push(c);
}

static void add_sender_addr(char c, void *p)
{
    p=p;
    if (c == '\n')    c=' ';
    sender_addr.push(c);
}

static const char *MyAddress()
{
struct    passwd *p=getpwuid(getuid());
Buffer    name;
const char *q;

static Buffer    buf;

    if (!p)    return ("");
    for (q=p->pw_name; *q; q++)
        if (!isalpha( (unsigned char)*q ) && *q != '_' && *q != ':' &&
            *q != '.')    break;

    if (!*q)    name=p->pw_name;
    else
    {
        name="\"";
        for (q=p->pw_name; *q; q++)
        {
            if (*q == '\\' || *q == '"')
                name.push('\\');
            name.push( (unsigned char)*q);
        }
        name += "\"";
    }
    if ( (q=HostName()) != 0)
    {
        name += '@';
        name += q;
    }

    if (!p->pw_gecos || !*p->pw_gecos)
        buf=name;
    else
    {
        buf="\"";
        for (q=p->pw_gecos; *q; q++)
        {
            if (*q == '\\' || *q == '"')
                buf.push('\\');
            buf.push ( (unsigned char)*q );
        }
        buf += "\" <";
        buf += name;
        buf += ">";
    }
    buf += '\0';
    return (buf);
}

//  Generate an autoreply header.

const char *get_autoreply();

const char *autoreply()
{
Buffer    from, reply_to, tos, ccs, envelope_from;
Buffer    message_id;
Buffer    newsgroups;
Buffer    newsgroup;
Buffer    references;
Buffer    subject;
Buffer    header;
Buffer    date;

const char *p, *q;

    autoreply_buf="";
    while ((p= (*from_filter)()) != 0 && *p != '\n')
    {
        header.reset();
        while (*p && *p != ':')
        {
        int    c= (unsigned char) *p++;

            c=tolower(c);
            header.push(c);
        }
        header += p;
        header += '\0';
        p=header;
        for (q=p; *q && *q != ':'; q++)
            ;
        if (*q == ':')    q++;
        while (*q && *q != '\n' && isspace(*q))    q++;

        if (strncmp(p, "from:", 5) == 0)    from=q;
        if (strncmp(p, "reply-to:", 9) == 0)    reply_to=q;
        if (strncmp(p, "to:", 3) == 0)
        {
            if (tos.Length())
            {
                tos.pop();
                tos += ",\n    ";
            }
            tos += q;
        }
        if (strncmp(p, "cc:", 3) == 0)
        {
            if (ccs.Length())
            {
                ccs.pop();
                ccs += ",\n    ";
            }
            ccs += q;
        }
        if (strncmp(p, "subject:", 8) == 0)
            subject=q;
        if (strncmp(p, "date:", 5) == 0)
            date=q;
        if (strncmp(p, "newsgroups:", 11) == 0)
            newsgroups=q;
        if (strncmp(p, "x-newsgroup:", 12) == 0)
            newsgroup=q;
        if (strncmp(p, "message-id:", 11) == 0)
            message_id=q;
        if (strncmp(p, "references:", 11) == 0)
            references=q;
        if (strncmp(p, "x-loop:", 7) == 0)
        {
            autoreply_buf += "X-Loop: ";
            autoreply_buf += q;
        }
        if (strncmp(p, "return-path:", 12) == 0 ||
            strncmp(p, ">return-path:", 13) == 0 ||
            strncmp(p, "errors-to:", 10) == 0 ||
            strncmp(p, ">errors-to:", 11) == 0)
        {
            envelope_from=q;
        }
    }

    autoreply_salutation.reset();

    autoreply_buf += "From: ";
    autoreply_buf += MyAddress();
    autoreply_buf += "\n";
    if (reply_to.Length())    from=reply_to;
    if (autoreply_envelope && envelope_from.Length())
            from=envelope_from;

    sender_name.reset();
    sender_addr.reset();
    if (from.Length())
    {
        autoreply_buf += "To: ";
        autoreply_buf += from;

    Buffer    tempbuf;

        tempbuf=from;
        tempbuf += '\0';

    struct rfc822t *rfc=rfc822t_alloc_new( (const char *)tempbuf, NULL,
                           NULL);

        if (!rfc)    outofmem();

    struct rfc822a *rfca=rfc822a_alloc( rfc);

        if (!rfca)    outofmem();

        rfc822_namelist(rfca, add_sender_name, NULL);
        rfc822_addrlist(rfca, add_sender_addr, NULL);
        rfc822a_free(rfca);
        rfc822t_free(rfc);
    }

    if (sender_addr.Length() == 0)
        sender_addr="someone";
    if (sender_name.Length() == 0)
        sender_name="someone";

char    c;

    while ((c=sender_addr.pop()) != 0 && isspace(c))
        ;
    if (c)    sender_addr.push(c);
    while ((c=sender_name.pop()) != 0 && isspace(c))
        ;
    if (c)    sender_name.push(c);

    if (salutation_template.Length() == 0)
        salutation_template="%F writes:%n";
    salutation_template += '\0';

Buffer    salutation_buf;

    for (p=salutation_template; *p; p++)
    {
        if (*p != '%' || p[1] == '\0')
        {
            salutation_buf.push( *p );
            continue;
        }
        switch (*++p)    {
        case 'n':
            salutation_buf.push('\n');
            continue;
        case 'C':
            salutation_buf += newsgroup;
            break;
        case 'i':
            salutation_buf += message_id;
            break;
        case 'N':
            salutation_buf += newsgroups;
            break;
        case 'f':
            salutation_buf += sender_addr;
            break;
        case 'F':
            salutation_buf += sender_name;
            break;
        case 'd':
            salutation_buf += date;
            break;
        case 's':
            salutation_buf += subject;
            break;
        default:
            salutation_buf.push (*p);
            break;
        }

        c=salutation_buf.pop();
        if (c && c != '\n')    salutation_buf.push(c);
    }

    salutation_buf += "\n";

    p=salutation_buf;

int    l=salutation_buf.Length();
int    i,j;

    i=0;
    while (i<l)
    {
        j= -1;

    int    n;

        for (n=i;n<l && n-i < 76; n++)
        {
            if ( p[n] == '\n')
            {
                j=n;
                break;
            }
            if ( isspace(p[n]))
                j=n;
        }
        if (j < 0) j=n;

        autoreply_salutation.append(p+i, j-i);
        autoreply_salutation += '\n';
        i=j;
        while (i < l)
        {
            if (p[i] == '\n')
            {
                ++i;
                break;
            }
            if (!isspace(p[i]))    break;
            ++i;
        }
    }

    if (autoreply_opts && (*autoreply_opts == 'a' || *autoreply_opts == 'A')
        && tos.Length())
    {
        autoreply_buf += "To: ";
        autoreply_buf += tos;
    }

    if (autoreply_opts && *autoreply_opts == 'A' && ccs.Length())
    {
        autoreply_buf += "Cc: ";
        autoreply_buf += ccs;
    }

    if (message_id.Length())
    {
        autoreply_buf += "In-Reply-To: ";
        autoreply_buf += message_id;

        if (references.Length())
            references += "      ";
        references += message_id;
    }
    if (references.Length())
    {
        autoreply_buf += "References: ";
        autoreply_buf += references;
    }
    if (newsgroups.Length())
    {
        autoreply_buf += "Newsgroups: ";
        autoreply_buf += newsgroups;
    }
    if (subject.Length())
    {
        subject += '\0';
        p=subject;
        if ( tolower( (unsigned char)*p ) == 'r' &&
            tolower( (unsigned char)p[1] ) == 'e')
        {
            q=p+2;
            if (*q == '[')
            {
                do
                {
                    ++q;
                } while ( isdigit( (unsigned char)*q ));
                if (*q == ']')    ++q;
                else q=p+2;
            }
            if (*q == ':')
            {
                p=q+1;
                while ( *p && *p != '\n' && isspace(
                    (unsigned char)*p))    p++;
            }
        }
        autoreply_buf += "Subject: Re: ";
        autoreply_buf += p;
    }

    autoreply_buf += '\0';
    autoreply_buf_ptr=autoreply_buf;
    return (get_autoreply());
}

const char *get_autoreply_body();

const char *get_autoreply()
{
    autoreply_ptr= &get_autoreply;
    if (*autoreply_buf_ptr == '\0')
    {
        autoreply_ptr= &get_autoreply_body;
        return ("\n");
    }

static Buffer    buf;

    buf.reset();
    do
    {
        while (*autoreply_buf_ptr)
        {
            buf.push (*autoreply_buf_ptr);
            if (*autoreply_buf_ptr++ == '\n')    break;
        }
    } while ( *autoreply_buf_ptr &&
        isspace( (unsigned char) *autoreply_buf_ptr ));
    buf += '\0';
    return (buf);
}

////////////////////////////////////////////////////////////////////////////
//
// Return TRUE if header is already in a list of headers.
//
// hdrs: null separated list of headers (and header contents)
// hdr - header to check (must be lowercase and terminated by a colon)
// pos - offset into hdrs where it's found.
//

static int has_hdr(const Buffer &hdrs, const char *hdr, unsigned &pos)
{
const char *r=hdrs;
int l=hdrs.Length();
Buffer    buf2;
unsigned pos2=0;

    while (l)
    {
        buf2.reset();
        pos=pos2;
        while (l)
        {
            --l;
            ++pos2;
            buf2.push( tolower(*r));
            if (*r++ == 0)    break;
        }
        buf2.push('\0');
        if (strncmp(hdr, buf2, strlen(hdr)) == 0)    return (1);
    }
    return (0);
}

static int has_hdr(const Buffer &hdrs, const char *hdr)
{
unsigned dummy;

    return (has_hdr(hdrs, hdr, dummy));
}

static void strip_empty_header(Buffer &buf)
{
Buffer    newbuf;
int l;
const char *p;

    for (p=buf, l=buf.Length(); l; )
    {
        if (p[strlen(p)-1] == ':')
        {
            while (l)
            {
                --l;
                if (*p++ == '\0')    break;
            }
            continue;
        }
        while (l)
        {
            --l;
            newbuf.push( *p );
            if (*p++ == '\0')    break;
        }
    }
    buf=newbuf;
}

static void strip_header(Buffer &header, unsigned offset)
{
Buffer    buf1;
const char *p=header;
int l=header.Length();

    while (l)
    {
        if (!offset)
        {
            while (l)
            {
                --l;
                if (*p++ == '\0')    break;
            }
            break;
        }
        buf1.push( *p++ );
        --l;
        --offset;
    }
    while (l--)
        buf1.push( *p++ );
    header=buf1;
}

const char *ReadLineAddNewHeader();

const char *ReadLineAddHeader()
{
Buffer    buf1;
const char *q;
const char *p;
unsigned pos;
static Buffer oldbuf;

    for (;;)
    {
        p= (*autoreply_ptr)();

        if (!p)    return p;
        if (*p == '\n')
        {
            strip_empty_header(opti);
            strip_empty_header(optI);
            return ( ReadLineAddNewHeader());
        }
        buf1.reset();
        for (q=p; *q && *q != '\n'; q++)
        {
            buf1.push( tolower(*q) );
            if (*q == ':')    break;
        }
        buf1 += '\0';

        if (has_hdr(opti, buf1))
        {
            oldbuf="old-";
            oldbuf += buf1;
            buf1=oldbuf;

        Buffer    tbuf;

            tbuf="Old-";
            tbuf += p;
            oldbuf=tbuf;
            oldbuf += '\0';
            p=oldbuf;
        }
        if (has_hdr(optR, buf1, pos))
        {
        Buffer    tbuf;

            q=optR;
            q += pos + strlen(buf1);
            tbuf=q;

            p += strlen(buf1);
            tbuf += p;
            oldbuf=tbuf;
            oldbuf += '\0';
            p=oldbuf;
        }

        if (has_hdr(optI, buf1))
            continue;
        if (has_hdr(optu, buf1))
        {
            if (!has_hdr(optubuf, buf1))
            {
                q=p;
                do
                {
                    optubuf.push( *q );
                } while (*q++);
                break;
            }
            continue;
        }

        if (has_hdr(optU, buf1))
        {
            if (has_hdr(optUbuf, buf1, pos))
                strip_header(optUbuf, pos);
            while (*p)
            {
                optUbuf.push( *p );
                p++;
            }
            optUbuf.pop();
            optUbuf.push('\0');
            continue;
        }
        break;
    }

unsigned offset;

    if (has_hdr(opta, buf1, offset))
        strip_header(opta, offset);
    return (p);
}

const char *ReadLineAddNewHeaderDone();

const char *ReadLineAddNewHeader()
{
    append_more_headers= &ReadLineAddNewHeader;

Buffer    *bufptr;

    if (opta.Length())    bufptr= &opta;
    else if (optA.Length())    bufptr= &optA;
    else if (opti.Length())    bufptr= &opti;
    else if (optI.Length())    bufptr= &optI;
    else if (optUbuf.Length())    bufptr= &optUbuf;
    else
    {
        append_more_headers=&ReadLineAddNewHeaderDone;
        return ("\n");
    }

static Buffer buf1;
Buffer    buf2;

    buf1.reset();

const char *p= *bufptr;
int l= bufptr->Length();

    while (l)
    {
        if ( !*p )
        {
            p++;
            l--;
            break;
        }
        buf1.push( *p );
        p++;
        l--;
    }
    buf1.push('\n');
    buf1.push('\0');

    while (l--)
        buf2.push (*p++);
    *bufptr=buf2;
    return (buf1);
}

const char *ReadLineAddNewHeaderDone()
{
    return ( (*autoreply_ptr)() );
}

////////////////////////////////////////////////////////////////////////////
const char *ReadLine()
{
const char *p=(*append_more_headers)();

    if (!p)    return (p);

static Buffer    buf;

    if (*p == '\n')
        inbody=1;

    if (catenate && !inbody)
    {
    const char *q;

        buf.reset();
        for (q=p; *q; q++)
        {
            if (*q != '\n')
            {
                buf.push(*q);
                continue;
            }
            do
            {
                ++q;
            } while (*q && isspace(*q));
            if (*q)
                buf.push(' ');
            --q;
        }
        if (addcrs)    buf.push('\r');
        buf.push('\n');
        buf.push('\0');
        return (buf);
    }

    if (addcrs)
    {
        buf=p;
        buf.pop();
        buf += "\r\n";
        buf += '\0';
        return (buf);
    }
    return (p);
}

const char *get_autoreply_body()
{
    if (!keep_body)
    {
#ifdef    BUFSIZ
    char    buf[BUFSIZ];
#else
    char    buf[512];    // Flush body to prevent broken pipe
#endif

        while ( !std::cin.eof())
            std::cin.read(buf, sizeof(buf));
        return (0);
    }

static Buffer    buf;

    if (autoreply_salutation.Length())
    {
    const    char *p;
    int    l;
    int    cnt;

        buf=autoreply_salutation;

        p=buf;
        l=buf.Length();
        cnt=0;
        while (l)
        {
            ++cnt;
            --l;
            if (*p++ == '\n')    break;
        }
        autoreply_salutation.reset();
        autoreply_salutation.append(p, l);
        buf.Length(cnt);
        buf += '\0';
        return (buf);
    }

const char *p= (*from_filter)();
    if (!p)    return(p);

    buf=autoreply_pfix;
    buf += p;
    buf += '\0';
    return (buf);
}

/////////////////////////////////////////////////////////////////////////
//
// Default activity: just copy the message (let the low-level format
// filters do their job.
//
/////////////////////////////////////////////////////////////////////////

void copy(int, char *[], int)
{
const char *p;

    while ((p= ReadLine()) != 0)
        std::cout << p;
}

void cache(int, char *[], int)
{
const char *p;
Buffer    buf;
int found=0;

    addcrs=0;
    while ((p= ReadLine()) != 0)
    {
    int    c;

        if (inbody)    break;
        buf.reset();
        while (*p && *p != '\n')
        {
            c= (unsigned char)*p;
            c=tolower(c);
            buf.push(c);
            if (*p++ == ':')    break;
        }
        if (!(buf == "message-id:"))    continue;
        buf += '\0';
        while (*p && isspace( (unsigned char)*p))    p++;
        buf.reset();
        while (*p)
        {
            buf.push(*p);
            ++p;
        }

        while ( (c=(unsigned char)buf.pop()) != 0 && isspace(c))
            ;
        if (c)    buf.push(c);
        if (buf.Length() == 0)    break;
        buf.push('\0');

    int    fd=open(cache_name, O_RDWR | O_CREAT, 0600);

        if (fd < 0)
        {
            perror("open");
            exit(75);
        }

        if (ll_lock_ex(fd) < 0)
        {
            perror("lock");
            exit(75);
        }

    off_t    pos=0;

        if (lseek(fd, 0L, SEEK_END) == -1 ||
            (pos=lseek(fd, 0L, SEEK_CUR)) == -1 ||
            lseek(fd, 0L, SEEK_SET) == -1)
        {
            perror("seek");
            exit(75);
        }

    off_t    maxlen_n=atol(cache_maxlen);
    char    *charbuf;
    off_t    newpos=maxlen_n;

        if (newpos < pos)    newpos=pos;

        if ((charbuf=new char[newpos+buf.Length()+1]) == NULL)
            outofmem();

    off_t    readcnt=read(fd, charbuf, newpos);

        if (readcnt < 0)    perror("read");

    char *q, *r;

        for (q=r=charbuf; q<charbuf+readcnt; )
        {
            if (*q == '\0')    break;    // Double null terminator
            if (strcmp( (const char *)buf, q) == 0)
            {
                found=1;
                while (q < charbuf+readcnt)
                    if (*q++ == '\0')    break;
            }
            else while (q < charbuf+readcnt)
                if ( (*r++=*q++) == '\0') break;
        }
        memcpy(r, (const char *)buf, buf.Length());
        r += buf.Length();
        for (q=charbuf; q<r; )
        {
            if (r - q < maxlen_n)
                break;
            while (q < r)
                if (*q++ == '\0')    break;
        }
        if (q == r)    q=charbuf;
        *r++ = '\0';
        if (lseek(fd, 0L, SEEK_SET) == -1)
        {
            perror("lseek");
            exit(1);
        }
        while (q < r)
        {
            readcnt=write(fd, q, r-q);
            if (readcnt == -1)
            {
                perror("write");
                exit(1);
            }
            q += readcnt;
        }
        close(fd);
        delete[] charbuf;
        break;
    }
    while ((p= ReadLine()) != 0)
        ;
    exit(found ? 0:1);
}

//////////////////////////////////////////////////////////////////////////
//
// Extract headers

void extract_headers(int, char *[], int)
{
const char *p, *q;
Buffer    b;

    catenate=1;
    while ((p=ReadLine()) && !inbody)
    {
        b.reset();
        for (q=p; *q && *q != '\n'; )
        {
        int    c= (unsigned char)*q;

            b.push( tolower(c) );
            if ( *q++ == ':')    break;
        }
        b.push(0);

        if (has_hdr(optx, b))
        {
            while (*q && *q != '\n' && isspace(*q))
                q++;
            std::cout << q;
            continue;
        }

        if (has_hdr(optX, b))
        {
            std::cout << p;
            continue;
        }
    }
    if (!std::cin.seekg(0, std::ios::end).fail())
        return;
    std::cin.clear();

    while ( ReadLine() )
        ;
}
//////////////////////////////////////////////////////////////////////////
//
// Split mbox file into messages.

void split(int argc, char *argv[], int argn)
{
const char *p;
Buffer    buf;
int    l;
int    do_environ=1;
unsigned long    environ=0;
unsigned    environ_len=3;
const    char *env;

    if (argn >= argc)    help();

    while ( (p=NextLine()) && *p == '\n')
        ;

    signal(SIGCHLD, SIG_DFL);
    signal(SIGPIPE, SIG_IGN);
    env=getenv("FILENO");
    if (env)
    {
    const char *q;

        for (q=env; *q; q++)
            if (!isdigit(*q))    break;
        if (*q)    do_environ=0;
        else
        {
            environ_len=strlen(env);
            environ=atol(env);
        }
    }

    while (p)
    {
    int    fds[2];

        if (pipe(fds) < 0)
        {
            std::cerr << "reformail: pipe() failed." << std::endl;
            exit(1);
        }

    pid_t    pid=fork();

        if (pid == -1)
        {
            std::cerr << "reformail: fork() failed." << std::endl;
            exit(1);
        }

        if (pid == 0)
        {
            dup2(fds[0], 0);
            close(fds[0]);
            close(fds[1]);

        Buffer    buf, buf2;

            if (do_environ)
            {
            char    *s;

                while (environ || environ_len)
                {
                    buf.push( "0123456789"[environ % 10]);
                    environ /= 10;
                    if (environ_len)    --environ_len;
                }

                buf2="FILENO=";
                while (buf.Length())
                    buf2.push(buf.pop());
                buf2 += '\0';
                s=strdup(buf2);
                if (!s)
                {
                    perror("strdup");
                    exit (1);
                }
                putenv(s);
            }

            execvp( argv[argn], argv+argn);
            std::cerr << "reformail: exec() failed." << std::endl;
            exit(1);
        }
        close(fds[0]);
        environ++;

        do
        {
            buf=p;
            p=ReadLine();
            if (!p || strncmp(p, "From ", 5) == 0)
                buf.pop();    // Drop trailing newline
            else
            {
                if (addcrs)
                {
                    buf.pop();
                    buf.push('\r');
                    buf.push('\n');
                }
            }

        const char *q=buf;

            l=buf.Length();
            while (l)
            {
            int    n= ::write( fds[1], q, l);
                if (n <= 0)
                {
                    std::cerr
                      << "reformail: write() failed."
                      << std::endl;
                    exit(1);
                }
                q += n;
                l -= n;
            }
        } while (p && strncmp(p, "From ", 5));
        close(fds[1]);

    int    wait_stat;

        while ( wait(&wait_stat) != pid )
            ;
        if (!WIFEXITED(wait_stat) || WEXITSTATUS(wait_stat))
            break;    // Rely on diagnostic from child
    }
}

//////////////////////////////////////////////////////////////////////////////

static void add_bin64(Buffer &buf, unsigned long n)
{
int    i;

    for (i=0; i<16; i++)
    {
        buf.push ( "0123456789ABCDEF"[n % 16] );
        n /= 16;
    }
}

static void add_messageid(Buffer &buf)
{
time_t    t;

    buf.push('<');
    time(&t);
    add_bin64(buf,t);
    buf.push('.');
    add_bin64(buf, getpid() );
    buf += ".reformail@";
    buf += HostName();
    buf.push('>');
}

static void add_opta(Buffer &buf, const char *optarg)
{
Buffer    chk_buf;
const char *c;

    for (c=optarg; *c; c++)
        chk_buf.push ( tolower( (unsigned char)*c ));
    if (chk_buf == "message-id:" || chk_buf == "resent_message_id:")
    {
        chk_buf=optarg;
        chk_buf += ' ';
        add_messageid(chk_buf);
        chk_buf += '\0';
        optarg=chk_buf;
    }

    do
    {
        buf.push( *optarg );
    } while (*optarg++);
}

int main(int argc, char *argv[])
{
int    argn, done;
const char    *optarg;
void    (*function)(int, char *[], int)=0;

#if HAVE_SETLOCALE
    setlocale(LC_ALL, "C");
#endif

    from_filter= &no_from_filter;
    autoreply_ptr= &no_autoreply;
    append_more_headers=&ReadLineAddHeader;
    done=0;
    for (argn=1; argn<argc; argn++)
    {
        if (strcmp(argv[argn], "--") == 0 || strcmp(argv[argn],"-")==0)
        {
            ++argn;
            break;
        }
        if (argv[argn][0] != '-')    break;
        optarg=argv[argn]+2;
        if (!*optarg)    optarg=0;
        switch ( argv[argn][1] )    {
        case 'd':
            if (!optarg || !*optarg)    optarg="1";
            addcrs=atoi(optarg);
            break;
        case 'c':
            catenate=1;
            break;
        case 'f':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || *optarg == '0')
                from_filter=&rem_from_filter;
            else
                from_filter=&add_from_filter;
            break;
        case 'r':
            if (function)    help();
            autoreply_ptr= &autoreply;
            autoreply_opts=optarg;
            break;
        case 'p':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            autoreply_pfix=optarg;
            break;
        case 'k':
            keep_body=1;
            break;
        case 't':
            autoreply_envelope=0;
            break;
        case 'D':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || argn+1 >= argc)    help();
            if (function)    help();
            function=cache;
            cache_maxlen=optarg;
            cache_name=argv[++argn];
            break;
        case 'a':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            add_opta(opta, optarg);
            break;
        case 'A':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            add_opta(optA, optarg);
            break;
        case 'i':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            do
            {
                opti.push( *optarg );
            } while (*optarg++);
            break;
        case 'I':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            do
            {
                optI.push( *optarg );
            } while (*optarg++);
            break;
        case 'R':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            while (*optarg)
                optR.push(*optarg++);
            if (argn+1 >= argc)    help();
            optarg=argv[++argn];
            while (*optarg)
                optR.push(*optarg++);
            optR.push(0);
            break;
        case 'u':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            while (*optarg)
                optu.push(*optarg++);
            optu.push(0);
            break;
        case 'U':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            while (*optarg)
                optU.push(*optarg++);
            optU.push(0);
            break;
        case 'x':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            while (*optarg)
                optx.push(*optarg++);
            optx.push(0);
            break;
        case 'X':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            if (function)    help();
            while (*optarg)
                optX.push(*optarg++);
            optX.push(0);
            break;
        case 's':
            if (function)    help();
            function= &split;
            ++argn;
            done=1;
            break;
        case 'P':
            if (!optarg && argn+1 < argc)    optarg=argv[++argn];
            if (!optarg || !*optarg)    help();
            salutation_template=optarg;
            break;
        default:
            help();
        }
        if (done)    break;
    }
    if (optx.Length() || optX.Length())
    {
        if (function)    help();
        function=extract_headers;
    }

    if (!function)    function=copy;
    (*function)(argc, argv, argn);
    std::cout.flush();
    if (std::cout.fail())
    {
        std::cerr << "reformail: error writing output." << std::endl;
        exit(1);
    }
    exit(0);
}
Command:
Quick Commands:
Upload:
[Read-Only] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [Read-Only]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.2404 seconds