コード例 #1
0
ファイル: deliver.cpp プロジェクト: copernicus/aox
    void execute()
    {
        if ( q && !q->done() )
            return;

        if ( q && q->done() && !p ) {
            Row * r = q->nextRow();
            q = 0;
            if ( !r )
                quit( EX_NOUSER, "No such user: "******"login" ) &&
                 r->getEString( "login" ) == "anonymous" )
                quit( EX_DATAERR, "Cannot deliver to the anonymous user" );
            if ( mbn.isEmpty() ) {
                mb = Mailbox::find( r->getInt( "mailbox" ) );
            }
            else {
                UString pre;
                if ( !r->isNull( "namespace" ) && !mbn.startsWith( "/" ) )
                    pre = r->getUString( "namespace" ) + "/" +
                          r->getUString( "login" ) + "/";
                mb = Mailbox::find( pre + mbn );
                User * u = new User;
                UString anyone;
                anyone.append( "anyone" );
                u->setLogin( anyone );
                if ( mb )
                    p = new Permissions( mb, u, this );
            }
            if ( !mb )
                quit( EX_CANTCREAT, "No such mailbox" );
        }

        if ( p && !p->ready() )
            return;

        if ( p && !p->allowed( Permissions::Post ) )
            quit( EX_NOPERM,
                  "User 'anyone' does not have 'p' right on mailbox " +
                  mbn.ascii().quoted( '\'' ) );

        if ( !i ) {
            EStringList x;
            m->setFlags( mb, &x );
            i = new Injector( this );
            List<Injectee> y;
            y.append( m );
            i->addInjection( &y );
            i->execute();
        }

        if ( !i->done() )
            return;

        if ( i->failed() )
            quit( EX_SOFTWARE, "Injection error: " + i->error() );

        i = 0;
        EventLoop::shutdown();
    }
コード例 #2
0
ファイル: mailbox.cpp プロジェクト: aox/aox
void MailboxReader::execute() {
    while ( q->hasResults() ) {
        Row * r = q->nextRow();

        UString n = r->getUString( "name" );
        uint id = r->getInt( "id" );
        Mailbox * m = ::mailboxes->find( id );
        if ( !m || m->name() != n ) {
            m = Mailbox::obtain( n );
            if ( n != m->d->name )
                m->d->name = n;
            m->setId( id );
            ::mailboxes->insert( id, m );
        }

        if ( r->getBoolean( "deleted" ) )
            m->setType( Mailbox::Deleted );
        else
            m->setType( Mailbox::Ordinary );

        uint uidvalidity = r->getInt( "uidvalidity" );
        if ( m->d->uidvalidity != uidvalidity ) {
            m->d->uidvalidity = uidvalidity;
            m->abortSessions();
        }
        if ( !r->isNull( "owner" ) )
            m->setOwner( r->getInt( "owner" ) );

        m->setUidnextAndNextModSeq( r->getInt( "uidnext" ),
                                    r->getBigint( "nextmodseq" ),
                                    q->transaction() );

        m->setFlag( r->getEString( "flag" ) );
    }

    if ( !q->done() || done )
        return;

    done = true;
    if ( q->transaction() )
        q->transaction()->commit();
    ::readers->remove( this );
    ::wiped = false;
    if ( q->failed() && !EventLoop::global()->inShutdown() ) {
        List<Mailbox> * c = Mailbox::root()->children();
        if ( c && !c->isEmpty() )
            log( "Couldn't update mailbox tree: " + q->error() );
        else
            log( "Couldn't create mailbox tree: " + q->error(),
                 Log::Disaster );
    }
    if ( owner )
        owner->execute();
};
コード例 #3
0
ファイル: database.cpp プロジェクト: aox/aox
        void execute()
        {
            if ( !q ) {
                q = new Query( "select not exists (select * from "
                               "information_schema.table_privileges where "
                               "privilege_type='DELETE' and table_name="
                               "'messages' and grantee=$1) and not exists "
                               "(select u.usename from pg_catalog.pg_class c "
                               "left join pg_catalog.pg_user u on "
                               "(u.usesysid=c.relowner) where c.relname="
                               "'messages' and u.usename=$1) as allowed",
                               this );
                q->bind( 1, Configuration::text( Configuration::DbUser ) );
                q->execute();
            }

            if ( !q->done() )
                return;

            Row * r = q->nextRow();
            if ( q->failed() || !r ||
                 r->getBoolean( "allowed" ) == false )
            {
                EString s( "Refusing to start because we have too many "
                          "privileges on the messages table in secure "
                          "mode." );
                result->setError( s );
                l->log( s, Log::Disaster );
                if ( q->failed() ) {
                    l->log( "Query: " + q->description(), Log::Disaster );
                    l->log( "Error: " + q->error(), Log::Disaster );
                }
            }
            else {
                result->setState( Query::Completed );
            }

            result->notify();
        }
コード例 #4
0
ファイル: pop.cpp プロジェクト: netconstructor/aox
            void execute()
            {
                if ( !r ) {
                    r = new RetentionSelector( mailbox, this );
                    r->execute();
                }

                if ( !t ) {
                    t = new ::Transaction( this );
                    nms = new Query( "select nextmodseq from mailboxes "
                                     "where id=$1 for update", this );
                    nms->bind( 1, mailbox->id() );
                    t->enqueue( nms );
                    t->execute();
                }

                if ( nms ) {
                    if ( !r->done() )
                        return;

                    if ( !nms->done() )
                        return;

                    ms = nms->nextRow()->getBigint( "nextmodseq" );
                    nms = 0;

                    Selector * s = new Selector;
                    if ( r->retains() ) {
                        Selector * n = new Selector( Selector::Not );
                        s->add( n );
                        n->add( r->retains() );
                    }
                    s->add( new Selector( this->s ) );
                    s->simplify();
                    EStringList wanted;
                    wanted.append( "mailbox" );
                    wanted.append( "uid" );
                    wanted.append( "message" );
                    iq = s->query( 0, mailbox, 0, this, false,
                                   &wanted, false );
                    int i = iq->string().find( " from " );
                    uint msb = s->placeHolder();
                    uint ub = s->placeHolder();
                    uint rb = s->placeHolder();
                    iq->setString(
                        "insert into deleted_messages "
                        "(mailbox,uid,message,modseq,deleted_by,reason) " +
                        iq->string().mid( 0, i ) + ", $" + fn( msb ) +", $" +
                        fn( ub ) + ", $" + fn( rb ) + iq->string().mid( i ) );
                    iq->bind( msb, ms );
                    iq->bind( ub, user->id() );
                    iq->bind( rb,
                             "POP delete " + Scope::current()->log()->id() );
                    t->enqueue( iq );
                    t->execute();
                }

                if ( iq ) {
                    if ( !iq->done() )
                        return;

                    if ( iq->rows() ) {
                        // at least one message was deleted
                        Query * q = new Query( "update mailboxes set "
                                               "nextmodseq=$1 where id=$2",
                                               this );
                        q->bind( 1, ms+1 );
                        q->bind( 2, mailbox->id() );
                        t->enqueue( q );
                        Mailbox::refreshMailboxes( t );
                    }
                    iq = 0;
                    t->commit();
                }

                if ( !t->done() )
                    return;

                if ( t->failed() )
                    log( "Error deleting messages: " + t->error() );
            }