// dbshell.cpp #include #ifdef USE_READLINE #include #include #endif #include "../scripting/engine.h" #include "../client/dbclient.h" #include "utils.h" extern const char * jsconcatcode; void shellHistoryInit(){ #ifdef USE_READLINE using_history(); read_history( ".dbshell" ); #else cout << "type \"exit\" to exit" << endl; #endif } void shellHistoryDone(){ #ifdef USE_READLINE write_history( ".dbshell" ); #endif } void shellHistoryAdd( const char * line ){ if ( strlen(line) == 0 ) return; #ifdef USE_READLINE add_history( line ); #endif } char * shellReadline( const char * prompt ){ #ifdef USE_READLINE return readline( "> " ); #else printf( "> " ); char * buf = new char[1024]; char * l = fgets( buf , 1024 , stdin ); int len = strlen( buf ); buf[len-1] = 0; return l; #endif } #if !defined(_WIN32) #include #include void quitNicely( int sig ){ shellHistoryDone(); exit(0); } /* use "addr2line -CFe " to parse. */ inline void printStackTrace() { void *b[20]; size_t size; char **strings; size_t i; size = backtrace(b, 20); strings = backtrace_symbols(b, size); for (i = 0; i < size; i++) cout << hex << b[i] << ' '; cout << '\n'; for (i = 0; i < size; i++) cout << ' ' << strings[i] << '\n'; cout << dec; free (strings); } void quitAbruptly( int sig ) { cout << "mongo got signal " << sig << " (" << strsignal( sig ) << "), stack trace: " << endl; printStackTrace(); mongo::shellUtils::KillMongoProgramInstances(); exit(14); } void setupSignals() { signal( SIGINT , quitNicely ); signal( SIGTERM , quitNicely ); signal( SIGPIPE , quitNicely ); // Maybe just log and continue? signal( SIGABRT , quitAbruptly ); signal( SIGSEGV , quitAbruptly ); signal( SIGBUS , quitAbruptly ); signal( SIGFPE , quitAbruptly ); } #else inline void setupSignals() {} #endif string fixHost( string url , string host , string port ){ if ( host.size() == 0 && port.size() == 0 ){ if ( url.find( "/" ) == string::npos && url.find( "." ) != string::npos ) return url + "/test"; return url; } if ( url.find( "/" ) != string::npos ){ cerr << "url can't have host or port if you specify them individually" << endl; exit(-1); } if ( host.size() == 0 ) host = "127.0.0.1"; string newurl = host; if ( port.size() > 0 ) newurl += ":" + port; newurl += "/" + url; return newurl; } int main(int argc, char* argv[]) { setupSignals(); mongo::shellUtils::RecordMyLocation( argv[ 0 ] ); mongo::ScriptEngine::setup(); auto_ptr< mongo::Scope > scope( mongo::globalScriptEngine->createScope() ); string url = "test"; string dbhost; string port; string username; string password; bool runShell = false; bool nodb = false; string script; int argNumber = 1; for ( ; argNumber < argc; argNumber++) { const char* str = argv[argNumber]; if (strcmp(str, "--shell") == 0) { runShell = true; continue; } if (strcmp(str, "--nodb") == 0) { nodb = true; continue; } if ( strcmp( str , "--port" ) == 0 ){ port = argv[argNumber+1]; argNumber++; continue; } if ( strcmp( str , "--host" ) == 0 ){ dbhost = argv[argNumber+1]; argNumber++; continue; } if ( strcmp( str , "--eval" ) == 0 ){ script = argv[argNumber+1]; argNumber++; continue; } if ( strcmp( str , "-u" ) == 0 ){ username = argv[argNumber+1]; argNumber++; continue; } if ( strcmp( str , "-p" ) == 0 ){ password = argv[argNumber+1]; argNumber++; continue; } if ( strstr( str , "-p" ) == str ){ password = str; password = password.substr( 2 ); continue; } if ( strcmp(str, "--help") == 0 || strcmp(str, "-h" ) == 0 ) { cout << "usage: " << argv[0] << " [options] [db address] [file names]\n" << "db address can be:\n" << " foo = foo database on local machine\n" << " 192.169.0.5/foo = foo database on 192.168.0.5 machine\n" << " 192.169.0.5:9999/foo = foo database on 192.168.0.5 machine on port 9999\n" << "options\n" << " --shell run the shell after executing files\n" << " -u \n" << " -p - notice no space\n" << " --host - server to connect to\n" << " --port - port to connect to\n" << " --nodb don't connect to mongo program on startup. No 'db address' arg expected.\n" << " --eval