void ListAliases::execute() { if ( !q ) { Utf8Codec c; UString pattern = c.toUnicode( next() ); end(); if ( !c.valid() ) error( "Argument encoding: " + c.error() ); database(); EString s( "select (localpart||'@'||domain)::text as address, m.name " "from aliases join addresses a on (address=a.id) " "join mailboxes m on (mailbox=m.id)" ); if ( !pattern.isEmpty() ) s.append( " where localpart||'@'||domain like $1 or " "m.name like $1" ); q = new Query( s, this ); if ( !pattern.isEmpty() ) q->bind( 1, sqlPattern( pattern ) ); q->execute(); } while ( q->hasResults() ) { Row * r = q->nextRow(); printf( "%s: %s\n", r->getEString( "address" ).cstr(), r->getUString( "name" ).utf8().cstr() ); } if ( !q->done() ) return; finish(); }
UString SmtpParser::subDomain() { EString e; char c = nextChar(); if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= '0' && c <= '9' ) || ( c >= 128 ) ) { do { e.append( c ); step(); c = nextChar(); } while ( ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= '0' && c <= '9' ) || ( c == '-' || c >= 128 ) ) ); } if ( e.isEmpty() && c == '.' ) setError( "Consecutive dots aren't permitted" ); else if ( e.isEmpty() ) setError( "Domain cannot end with a dot" ); else if ( e[e.length()-1] == '-' ) setError( "subdomain cannot end with hyphen (" + e + ")" ); else if ( e.startsWith( "xn--" ) ) setError( "subdomain cannot be an a-label (" + e + ")" ); Utf8Codec u; UString r = u.toUnicode( e ); if ( !u.valid() ) setError( "Subdomain (" + e + ") is not valid UTF8: " + u.error() ); return r; }
bool PopCommand::user() { if ( !d->user ) { log( "USER Command" ); if ( !d->pop->accessPermitted() ) { d->pop->err( "Must enable TLS before login" ); return true; } d->user = new ::User; Utf8Codec c; d->user->setLogin( c.toUnicode( nextArg() ) ); d->pop->setUser( d->user, "POP3 login" ); if ( c.valid() ) { d->user->refresh( this ); } else { d->pop->err( "Argument encoding error: " + c.error() ); d->pop->badUser(); return true; } } if ( d->user->state() == User::Unverified ) return false; if ( d->user->state() == User::Nonexistent ) { d->pop->err( "No such user" ); d->pop->badUser(); } else { d->pop->ok( "Done" ); } return true; }
UString SmtpParser::atom() { char c = nextChar(); EString r; while ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || ( c >= '0' && c <= '9' ) || c == '!' || c == '#' || c == '$' || c == '%' || c == '&' || c == '\'' || c == '*' || c == '+' || c == '-' || c == '/' || c == '=' || c == '?' || c == '^' || c == '_' || c == '`' || c == '{' || c == '|' || c == '}' || c == '~' || c >= 128 ) { r.append( c ); step(); c = nextChar(); } if ( r.isEmpty() ) setError( "Expected atom, saw: " + following() ); Utf8Codec uc; UString u = uc.toUnicode( r ); if ( !uc.valid() ) setError( "Unicode error in atom (" + uc.error() + "): " + r ); return u; }
UString SmtpParser::quotedString() { require( "\"" ); EString r; while ( ok() && !atEnd() && nextChar() != '"' ) { if ( nextChar() == '\\' ) step(); r.append( nextChar() ); step(); } require( "\"" ); Utf8Codec c; UString u = c.toUnicode( r ); if ( !c.valid() ) setError( "Unicode error in string (" + c.error() + "): " + r ); return u; }
UString SieveParser::quotedString() { EString r; require( "\"" ); while ( ok() && !atEnd() && nextChar() != '"' ) { if ( present( "\r\n" ) ) { r.append( "\r\n" ); } else { if ( nextChar() == '\\' ) step(); r.append( nextChar() ); step(); } } require( "\"" ); Utf8Codec c; UString u = c.toUnicode( r ); if ( !c.valid() ) setError( "Encoding error: " + c.error() ); return u; }
UString SieveParser::multiLine() { EString r; require( "text:" ); while ( ok() && ( nextChar() == ' ' || nextChar() == '\t' ) ) step(); if ( !present( "\r\n" ) ) hashComment(); while ( ok() && !atEnd() && !present( ".\r\n" ) ) { if ( nextChar() == '.' ) step(); while ( ok() && !atEnd() && nextChar() != '\r' ) { r.append( nextChar() ); step(); } require( "\r\n" ); r.append( "\r\n" ); } Utf8Codec c; UString u = c.toUnicode( r ); if ( !c.valid() ) setError( "Encoding error: " + c.error() ); return u; }
void CreateAlias::execute() { if ( !d->address ) { Utf8Codec c; parseOptions(); d->address = nextAsAddress(); EString * first = args()->firstElement(); if ( first && !first->startsWith( "/" ) && first->contains( "@" ) ) d->destination = nextAsAddress(); else d->mailboxName = c.toUnicode( next() ); end(); if ( !c.valid() ) error( "Argument encoding: " + c.error() ); database( true ); if ( !d->mailboxName.isEmpty() ) Mailbox::setup( this ); } if ( !choresDone() ) return; if ( !d->t ) { if ( !d->mailboxName.isEmpty() ) { d->mailbox = Mailbox::obtain( d->mailboxName, false ); if ( !d->mailbox || d->mailbox->deleted() ) error( "No mailbox named " + d->mailboxName.utf8() ); } d->t = new Transaction( this ); List< Address > l; l.append( d->address ); if ( d->destination ) l.append( d->destination ); AddressCreator * ac = new AddressCreator( &l, d->t ); ac->execute(); } if ( !d->address->id() || ( d->destination && !d->destination->id() ) ) return; if ( !d->q ) { if ( d->destination ) { d->q = new Query( "insert into aliases (address, mailbox) " "select $1, mailbox from aliases al " "join addresses a on (al.address=a.id) " "where a.localpart=$2" " and a.domain=$3 " "limit 1", this ); d->q->bind( 1, d->address->id() ); d->q->bind( 2, d->destination->localpart() ); d->q->bind( 3, d->destination->domain() ); } else { d->q = new Query( "insert into aliases (address, mailbox) " "values ($1, $2)", this ); d->q->bind( 1, d->address->id() ); d->q->bind( 2, d->mailbox->id() ); } d->t->enqueue( d->q ); d->t->execute(); } if ( !d->q->done() ) return; if ( d->q->failed() ) error( "Couldn't create alias: " + d->q->error() ); if ( d->q->rows() < 1 ) error( "Could not locate destination for alias" ); else if ( d->q->rows() > 1 ) error( "Internal error: Inserted " + fn( d->q->rows() ) + " instead of 1. Not committing." ); d->t->commit(); finish(); }
void CreateView::execute() { if ( d->name.isEmpty() ) { parseOptions(); Utf8Codec c; d->name = c.toUnicode( next() ); d->source = c.toUnicode( next() ); UString owner( c.toUnicode( next() ) ); d->selector = parseSelector( args() ); if ( !c.valid() ) error( "Argument encoding: " + c.error() ); if ( d->name.isEmpty() ) error( "No name supplied for the view." ); if ( d->source.isEmpty() ) error( "No source mailbox name supplied." ); if ( !d->selector ) error( "Invalid search expression supplied." ); database( true ); Mailbox::setup( this ); if ( !owner.isEmpty() ) { d->user = new User; d->user->setLogin( owner ); d->user->refresh( this ); } } if ( !choresDone() ) return; if ( !d->t ) { if ( d->user ) { if ( d->user->state() == User::Unverified ) return; if ( d->user->state() == User::Nonexistent ) error( "No user named " + d->user->login().utf8() ); if ( !d->name.startsWith( "/" ) ) d->name = d->user->home()->name() + "/" + d->name; if ( !d->source.startsWith( "/" ) ) d->source = d->user->home()->name() + "/" + d->source; } d->ms = Mailbox::obtain( d->source ); if ( !d->ms || d->ms->deleted() ) error( "Can't create view on " + d->source.utf8() ); d->t = new Transaction( this ); d->mv = Mailbox::obtain( d->name ); Query * q = d->mv->create( d->t, d->user ); if ( !q ) error( "Couldn't create view named " + d->name.utf8() ); q = new Query( "insert into views " "(view, selector, source, nextmodseq) values " "((select id from mailboxes where name=$1)," "$2, " "((select id from mailboxes where name=$3), " "1::bigint)", this ); q->bind( 1, d->name ); q->bind( 2, d->selector->string() ); q->bind( 3, d->ms->name() ); d->t->enqueue( q ); d->t->commit(); } if ( !d->t->done() ) return; if ( d->t->failed() ) error( "Couldn't create view" ); finish(); }
int main( int ac, char ** av ) { Scope global; bool bad = false; if ( ac < 1 ) bad = true; Configuration::setup( "archiveopteryx.conf" ); EventLoop::setup(); Log * l = new Log; Allocator::addEternal( l, "aoxexport log" ); global.setLog( l ); LogClient::setup( "aoxexport" ); Configuration::report(); int i = 1; while( i < ac && *av[i] == '-' ) { uint j = 1; while ( av[i][j] ) { switch( av[i][j] ) { case 'v': verbosity++; break; case 'q': if ( verbosity ) verbosity--; break; default: bad = true; break; } j++; } i++; } Utf8Codec c; UString source; if ( i >= ac ) bad = true; else if ( av[i][0] == '/' ) source = c.toUnicode( av[i++] ); Selector * which; if ( i < ac ) { EStringList args; while ( i < ac ) args.append( new EString( av[i++] ) ); which = parseSelector( &args ); } else { which = new Selector( Selector::NoField, Selector::All, 0 ); } if ( bad ) { fprintf( stderr, "Usage: %s [-vq] [mailbox] [search]" "See aoxexport(8) or " "http://aox.org/aoxexport/ for details.\n", av[0] ); exit( -1 ); } if ( !c.valid() ) { fprintf( stderr, "%s: Mailbox name could not be converted from UTF-8: %s\n", av[0], c.error().cstr() ); exit( -1 ); } Entropy::setup(); Database::setup(); Exporter * e = new Exporter( source, which ); Mailbox::setup( e ); EventLoop::global()->start(); return 0; }