summaryrefslogtreecommitdiff
path: root/src/mongo/shell/dbshell.cpp
diff options
context:
space:
mode:
authorApollon Oikonomopoulos <apoikos@debian.org>2016-01-14 00:10:06 +0200
committerApollon Oikonomopoulos <apollon@skroutz.gr>2016-01-14 00:10:06 +0200
commit374e1947abcd3e127a2a613aff73ecffdb9199ea (patch)
treed83973c3c9802450acd5b5e86fe0d4e8e60a3a1b /src/mongo/shell/dbshell.cpp
parent65585c90b12d6523bea75a2aebaae2a2fdf9e641 (diff)
Imported Upstream version 2.6.11upstream/2.6.11
Diffstat (limited to 'src/mongo/shell/dbshell.cpp')
-rw-r--r--src/mongo/shell/dbshell.cpp492
1 files changed, 202 insertions, 290 deletions
diff --git a/src/mongo/shell/dbshell.cpp b/src/mongo/shell/dbshell.cpp
index 5934e862076..e51e91aaf2e 100644
--- a/src/mongo/shell/dbshell.cpp
+++ b/src/mongo/shell/dbshell.cpp
@@ -24,15 +24,21 @@
#include <string.h>
#include "mongo/base/initializer.h"
+#include "mongo/base/status.h"
+#include "mongo/client/clientOnly-private.h"
#include "mongo/client/dbclientinterface.h"
#include "mongo/client/sasl_client_authenticate.h"
-#include "mongo/db/cmdline.h"
#include "mongo/db/repl/rs_member.h"
+#include "mongo/logger/console_appender.h"
+#include "mongo/logger/logger.h"
+#include "mongo/logger/message_event_utf8_encoder.h"
#include "mongo/scripting/engine.h"
#include "mongo/shell/linenoise.h"
+#include "mongo/shell/shell_options.h"
#include "mongo/shell/shell_utils.h"
#include "mongo/shell/shell_utils_launcher.h"
#include "mongo/util/file.h"
+#include "mongo/util/net/ssl_options.h"
#include "mongo/util/password.h"
#include "mongo/util/stacktrace.h"
#include "mongo/util/startup_test.h"
@@ -41,6 +47,7 @@
#ifdef _WIN32
#include <io.h>
+#include <shlobj.h>
#define isatty _isatty
#define fileno _fileno
#else
@@ -54,7 +61,6 @@ string historyFile;
bool gotInterrupted = false;
bool inMultiLine = false;
static volatile bool atPrompt = false; // can eval before getting to prompt
-bool autoKillOp = false;
#if !defined(__freebsd__) && !defined(__openbsd__) && !defined(_WIN32)
// this is for ctrl-c handling
@@ -75,7 +81,9 @@ void generateCompletions( const string& prefix , vector<string>& all ) {
try {
BSONObj args = BSON( "0" << prefix );
- shellMainScope->invokeSafe( "function callShellAutocomplete(x) {shellAutocomplete(x)}", &args, 0, 1000 );
+ shellMainScope->invokeSafe("function callShellAutocomplete(x) {shellAutocomplete(x)}",
+ &args,
+ NULL);
BSONObjBuilder b;
shellMainScope->append( b , "" , "__autocomplete__" );
BSONObj res = b.obj();
@@ -125,11 +133,16 @@ void shellHistoryAdd( const char * line ) {
return;
lastLine = line;
- // We don't want any .auth() or .addUser() commands added, but we want to
+ // We don't want any .auth() or .addUser() shell helpers added, but we want to
// be able to add things like `.author`, so be smart about how this is
// detected by using regular expresions.
- static pcrecpp::RE hiddenCommands("\\.(auth|addUser)\\s*\\(");
- if (!hiddenCommands.PartialMatch(line))
+ static pcrecpp::RE hiddenHelpers(
+ "\\.\\s*(auth|addUser|createUser|updateUser|changeUserPassword)\\s*\\(");
+ // Also don't want the raw user management commands to show in the shell when run directly
+ // via runCommand.
+ static pcrecpp::RE hiddenCommands(
+ "(run|admin)Command\\s*\\(\\s*{\\s*(createUser|updateUser)\\s*:");
+ if (!hiddenHelpers.PartialMatch(line) && !hiddenCommands.PartialMatch(line))
{
linenoiseHistoryAdd( line );
}
@@ -150,11 +163,15 @@ void killOps() {
sleepmillis(10); // give current op a chance to finish
- mongo::shell_utils::connectionRegistry.killOperationsOnAllConnections( !autoKillOp );
+ mongo::shell_utils::connectionRegistry.
+ killOperationsOnAllConnections(!shellGlobalParams.autoKillOp);
}
void quitNicely( int sig ) {
- mongo::dbexitCalled = true;
+ {
+ mongo::mutex::scoped_lock lk(mongo::shell_utils::mongoProgramOutputMutex);
+ mongo::dbexitCalled = true;
+ }
if ( sig == SIGINT && inMultiLine ) {
gotInterrupted = 1;
return;
@@ -208,13 +225,8 @@ char * strsignal(int sig){
#endif
void quitAbruptly( int sig ) {
- ostringstream ossSig;
- ossSig << "mongo got signal " << sig << " (" << strsignal( sig ) << "), stack trace: " << endl;
- mongo::rawOut( ossSig.str() );
-
- ostringstream ossBt;
- mongo::printStackTrace( ossBt );
- mongo::rawOut( ossBt.str() );
+ log() << "mongo got signal " << sig << " (" << strsignal( sig ) << "), stack trace: ";
+ mongo::printStackTrace();
mongo::shell_utils::KillMongoProgramInstances();
::_exit( 14 );
@@ -223,8 +235,7 @@ void quitAbruptly( int sig ) {
// this will be called in certain c++ error cases, for example if there are two active
// exceptions
void myterminate() {
- mongo::rawOut( "terminate() called in shell, printing stack:" );
- mongo::printStackTrace();
+ mongo::printStackTrace(severe().stream() << "terminate() called in shell, printing stack:\n");
::_exit( 14 );
}
@@ -299,6 +310,35 @@ bool isUseCmd( const std::string& code ) {
return cmd == "use";
}
+/**
+ * Skip over a quoted string, including quotes escaped with backslash
+ *
+ * @param code String
+ * @param start Starting position within string, always > 0
+ * @param quote Quote character (single or double quote)
+ * @return Position of ending quote, or code.size() if no quote found
+ */
+size_t skipOverString(const std::string& code, size_t start, char quote) {
+ size_t pos = start;
+ while (pos < code.size()) {
+ pos = code.find(quote, pos);
+ if (pos == std::string::npos) {
+ return code.size();
+ }
+ // We want to break if the quote we found is not escaped, but we need to make sure
+ // that the escaping backslash is not itself escaped. Comparisons of start and pos
+ // are to keep us from reading beyond the beginning of the quoted string.
+ //
+ if (start == pos || code[pos - 1] != '\\' || // previous char was backslash
+ start == pos - 1 || code[pos - 2] == '\\' // char before backslash was not another
+ ) {
+ break; // The quote we found was not preceded by an unescaped backslash; it is real
+ }
+ ++pos; // The quote we found was escaped with backslash, so it doesn't count
+ }
+ return pos;
+}
+
bool isBalanced( const std::string& code ) {
if (isUseCmd( code ))
return true; // don't balance "use <dbname>" in case dbname contains special chars
@@ -340,12 +380,11 @@ bool isBalanced( const std::string& code ) {
parens--;
break;
case '"':
- i++;
- while ( i < code.size() && code[i] != '"' ) i++;
- break;
case '\'':
- i++;
- while ( i < code.size() && code[i] != '\'' ) i++;
+ i = skipOverString(code, i + 1, code[i]);
+ if (i >= code.size()) {
+ return true; // Do not let unterminated strings enter multi-line mode
+ }
break;
case '\\':
if ( i + 1 < code.size() && code[i+1] == '/' ) i++;
@@ -382,15 +421,29 @@ public:
verify( ! isBalanced( "\"//\" {" ) );
verify( isBalanced( "{x:/x\\//}" ) );
verify( ! isBalanced( "{ \\/// }" ) );
- verify( isBalanced( "x = 5 + y ") );
- verify( ! isBalanced( "x = ") );
- verify( ! isBalanced( "x = // hello") );
- verify( ! isBalanced( "x = 5 +") );
- verify( isBalanced( " x ++") );
- verify( isBalanced( "-- x") );
- verify( !isBalanced( "a.") );
- verify( !isBalanced( "a. ") );
- verify( isBalanced( "a.b") );
+ verify( isBalanced( "x = 5 + y " ) );
+ verify( ! isBalanced( "x = " ) );
+ verify( ! isBalanced( "x = // hello" ) );
+ verify( ! isBalanced( "x = 5 +" ) );
+ verify( isBalanced( " x ++" ) );
+ verify( isBalanced( "-- x" ) );
+ verify( !isBalanced( "a." ) );
+ verify( !isBalanced( "a. " ) );
+ verify( isBalanced( "a.b" ) );
+
+ // SERVER-5809 and related cases --
+ verify( isBalanced( "a = {s:\"\\\"\"}" ) ); // a = {s:"\""}
+ verify( isBalanced( "db.test.save({s:\"\\\"\"})" ) ); // db.test.save({s:"\""})
+ verify( isBalanced( "printjson(\" \\\" \")" ) ); // printjson(" \" ") -- SERVER-8554
+ verify( isBalanced( "var a = \"\\\\\";" ) ); // var a = "\\";
+ verify( isBalanced( "var a = (\"\\\\\") //\"" ) ); // var a = ("\\") //"
+ verify( isBalanced( "var a = (\"\\\\\") //\\\"" ) ); // var a = ("\\") //\"
+ verify( isBalanced( "var a = (\"\\\\\") //" ) ); // var a = ("\\") //
+ verify( isBalanced( "var a = (\"\\\\\")" ) ); // var a = ("\\")
+ verify( isBalanced( "var a = (\"\\\\\\\"\")" ) ); // var a = ("\\\"")
+ verify( ! isBalanced( "var a = (\"\\\\\" //\"" ) ); // var a = ("\\" //"
+ verify( ! isBalanced( "var a = (\"\\\\\" //" ) ); // var a = ("\\" //
+ verify( ! isBalanced( "var a = (\"\\\\\"" ) ); // var a = ("\\"
}
} balanced_test;
@@ -420,31 +473,6 @@ string finishCode( string code ) {
return code;
}
-#include <boost/program_options.hpp>
-namespace po = boost::program_options;
-
-void show_help_text( const char* name, po::options_description options ) {
- cout << "MongoDB shell version: " << mongo::versionString << endl;
- cout << "usage: " << name << " [options] [db address] [file names (ending in .js)]" << endl
- << "db address can be:" << endl
- << " foo foo database on local machine" << endl
- << " 192.169.0.5/foo foo database on 192.168.0.5 machine" << endl
- << " 192.169.0.5:9999/foo foo database on 192.168.0.5 machine on port 9999" << endl
- << options << endl
- << "file names: a list of files to run. files have to end in .js and will exit after "
- << "unless --shell is specified" << endl;
-};
-
-bool fileExists( string file ) {
- try {
- boost::filesystem::path p( file );
- return boost::filesystem::exists( file );
- }
- catch ( ... ) {
- return false;
- }
-}
-
namespace mongo {
extern bool isShell;
}
@@ -529,7 +557,7 @@ static void edit( const string& whatToEdit ) {
sb << "/tmp/mongo_edit" << time( 0 ) + i << ".js";
#endif
filename = sb.str();
- if ( ! fileExists( filename ) )
+ if (!::mongo::shell_utils::fileExists(filename))
break;
}
if ( i == maxAttempts ) {
@@ -609,98 +637,14 @@ static void edit( const string& whatToEdit ) {
}
int _main( int argc, char* argv[], char **envp ) {
- mongo::runGlobalInitializersOrDie(argc, argv, envp);
mongo::isShell = true;
setupSignals();
mongo::shell_utils::RecordMyLocation( argv[ 0 ] );
- string url = "test";
- string dbhost;
- string port;
- vector<string> files;
-
- string username;
- string password;
- string authenticationMechanism;
- string authenticationDatabase;
-
- std::string sslPEMKeyFile;
- std::string sslPEMKeyPassword;
- std::string sslCAFile;
-
- bool runShell = false;
- bool nodb = false;
- bool norc = false;
-
- string script;
-
- po::options_description shell_options( "options" );
- po::options_description hidden_options( "Hidden options" );
- po::options_description cmdline_options( "Command line options" );
- po::positional_options_description positional_options;
-
- shell_options.add_options()
- ( "shell", "run the shell after executing files" )
- ( "nodb", "don't connect to mongod on startup - no 'db address' arg expected" )
- ( "norc", "will not run the \".mongorc.js\" file on start up" )
- ( "quiet", "be less chatty" )
- ( "port", po::value<string>( &port ), "port to connect to" )
- ( "host", po::value<string>( &dbhost ), "server to connect to" )
- ( "eval", po::value<string>( &script ), "evaluate javascript" )
- ( "username,u", po::value<string>(&username), "username for authentication" )
- ( "password,p", new mongo::PasswordValue( &password ), "password for authentication" )
- ("authenticationDatabase",
- po::value<string>(&authenticationDatabase)->default_value(""),
- "user source (defaults to dbname)" )
- ("authenticationMechanism",
- po::value<string>(&authenticationMechanism)->default_value("MONGODB-CR"),
- "authentication mechanism")
- ( "help,h", "show this usage information" )
- ( "version", "show version information" )
- ( "verbose", "increase verbosity" )
- ( "ipv6", "enable IPv6 support (disabled by default)" )
-#ifdef MONGO_SSL
- ( "ssl", "use SSL for all connections" )
- ( "sslCAFile", po::value<std::string>(&sslCAFile), "Certificate Authority for SSL" )
- ( "sslPEMKeyFile", po::value<std::string>(&sslPEMKeyFile), "PEM certificate/key file for SSL" )
- ( "sslPEMKeyPassword", po::value<std::string>(&sslPEMKeyFile),
- "password for key in PEM file for SSL" )
-#endif
- ;
-
- hidden_options.add_options()
- ( "dbaddress", po::value<string>(), "dbaddress" )
- ( "files", po::value< vector<string> >(), "files" )
- ( "nokillop", "nokillop" ) // for testing, kill op will also be disabled automatically if the tests starts a mongo program
- ( "autokillop", "autokillop" ) // for testing, will kill op without prompting
- ;
-
- positional_options.add( "dbaddress", 1 );
- positional_options.add( "files", -1 );
+ shellGlobalParams.url = "test";
- cmdline_options.add( shell_options ).add( hidden_options );
-
- po::variables_map params;
-
- /* using the same style as db.cpp uses because eventually we're going
- * to merge some of this stuff. */
- int command_line_style = (((po::command_line_style::unix_style ^
- po::command_line_style::allow_guessing) |
- po::command_line_style::allow_long_disguise) ^
- po::command_line_style::allow_sticky);
-
- try {
- po::store(po::command_line_parser(argc, argv).options(cmdline_options).
- positional(positional_options).
- style(command_line_style).run(), params);
- po::notify( params );
- }
- catch ( po::error &e ) {
- cout << "ERROR: " << e.what() << endl << endl;
- show_help_text( argv[0], shell_options );
- return mongo::EXIT_BADOPTIONS;
- }
+ mongo::runGlobalInitializersOrDie(argc, argv, envp);
// hide password from ps output
for ( int i = 0; i < (argc-1); ++i ) {
@@ -712,139 +656,81 @@ int _main( int argc, char* argv[], char **envp ) {
}
}
- if ( params.count( "shell" ) ) {
- runShell = true;
- }
- if ( params.count( "nodb" ) ) {
- nodb = true;
- }
- if ( params.count( "norc" ) ) {
- norc = true;
- }
- if ( params.count( "help" ) ) {
- show_help_text( argv[0], shell_options );
- return mongo::EXIT_CLEAN;
- }
- if ( params.count( "files" ) ) {
- files = params["files"].as< vector<string> >();
- }
- if ( params.count( "version" ) ) {
- cout << "MongoDB shell version: " << mongo::versionString << endl;
- return mongo::EXIT_CLEAN;
- }
- if ( params.count( "quiet" ) ) {
- mongo::cmdLine.quiet = true;
- }
-#ifdef MONGO_SSL
- if ( params.count( "ssl" ) ) {
- mongo::cmdLine.sslOnNormalPorts = true;
- }
- if (params.count("sslPEMKeyFile")) {
- mongo::cmdLine.sslPEMKeyFile = params["sslPEMKeyFile"].as<std::string>();
- }
- if (params.count("sslPEMKeyPassword")) {
- mongo::cmdLine.sslPEMKeyPassword = params["sslPEMKeyPassword"].as<std::string>();
- }
- if (params.count("sslCAFile")) {
- mongo::cmdLine.sslCAFile = params["sslCAFile"].as<std::string>();
- }
-#endif
- if ( params.count( "nokillop" ) ) {
- mongo::shell_utils::_nokillop = true;
- }
- if ( params.count( "autokillop" ) ) {
- autoKillOp = true;
- }
-
- /* This is a bit confusing, here are the rules:
- *
- * if nodb is set then all positional parameters are files
- * otherwise the first positional parameter might be a dbaddress, but
- * only if one of these conditions is met:
- * - it contains no '.' after the last appearance of '\' or '/'
- * - it doesn't end in '.js' and it doesn't specify a path to an existing file */
- if ( params.count( "dbaddress" ) ) {
- string dbaddress = params["dbaddress"].as<string>();
- if (nodb) {
- files.insert( files.begin(), dbaddress );
- }
- else {
- string basename = dbaddress.substr( dbaddress.find_last_of( "/\\" ) + 1 );
- if (basename.find_first_of( '.' ) == string::npos ||
- ( basename.find( ".js", basename.size() - 3 ) == string::npos && !fileExists( dbaddress ) ) ) {
- url = dbaddress;
- }
- else {
- files.insert( files.begin(), dbaddress );
- }
- }
- }
- if ( params.count( "ipv6" ) ) {
- mongo::enableIPv6();
- }
- if ( params.count( "verbose" ) ) {
- logLevel = 1;
- }
-
- if ( url == "*" ) {
- cout << "ERROR: " << "\"*\" is an invalid db address" << endl << endl;
- show_help_text( argv[0], shell_options );
- return mongo::EXIT_BADOPTIONS;
- }
-
- if ( ! mongo::cmdLine.quiet )
+ if (!mongo::serverGlobalParams.quiet)
cout << "MongoDB shell version: " << mongo::versionString << endl;
mongo::StartupTest::runTests();
- if ( !nodb ) { // connect to db
- //if ( ! mongo::cmdLine.quiet ) cout << "url: " << url << endl;
+ logger::globalLogManager()->getNamedDomain("javascriptOutput")->attachAppender(
+ logger::MessageLogDomain::AppenderAutoPtr(
+ new logger::ConsoleAppender<logger::MessageEventEphemeral>(
+ new logger::MessageEventUnadornedEncoder)));
+ if (!shellGlobalParams.nodb) { // connect to db
stringstream ss;
- if ( mongo::cmdLine.quiet )
+ if (mongo::serverGlobalParams.quiet)
ss << "__quiet = true;";
- ss << "db = connect( \"" << fixHost( url , dbhost , port ) << "\")";
+ ss << "db = connect( \""
+ << fixHost(shellGlobalParams.url, shellGlobalParams.dbhost, shellGlobalParams.port)
+ << "\")";
mongo::shell_utils::_dbConnect = ss.str();
- if ( params.count( "password" ) && password.empty() )
- password = mongo::askPassword();
-
- // Construct the authentication-related code to execute on shell startup.
- //
- // This constructs and immediately executes an anonymous function, to avoid
- // the shell's default behavior of printing statement results to the console.
- //
- // It constructs a statement of the following form:
- //
- // (function() {
- // // Set default authentication mechanism and, maybe, authenticate.
- // }())
- stringstream authStringStream;
- authStringStream << "(function() { " << endl;
- if ( !authenticationMechanism.empty() ) {
- authStringStream << "DB.prototype._defaultAuthenticationMechanism = \"" <<
- authenticationMechanism << "\";" << endl;
+ if (shellGlobalParams.usingPassword && shellGlobalParams.password.empty()) {
+ shellGlobalParams.password = mongo::askPassword();
}
+ }
- if ( username.size() ) {
- authStringStream << "var username = \"" << username << "\";" << endl;
- authStringStream << "var password = \"" << password << "\";" << endl;
- if (authenticationDatabase.empty()) {
- authStringStream << "var authDb = db;" << endl;
- }
- else {
- authStringStream << "var authDb = db.getSiblingDB(\"" << authenticationDatabase <<
- "\");" << endl;
- }
- authStringStream << "authDb._authOrThrow({ " <<
- saslCommandPrincipalFieldName << ": username, " <<
- saslCommandPasswordFieldName << ": password });" << endl;
+ // Construct the authentication-related code to execute on shell startup.
+ //
+ // This constructs and immediately executes an anonymous function, to avoid
+ // the shell's default behavior of printing statement results to the console.
+ //
+ // It constructs a statement of the following form:
+ //
+ // (function() {
+ // // Set default authentication mechanism and, maybe, authenticate.
+ // }())
+ stringstream authStringStream;
+ authStringStream << "(function() { " << endl;
+ if (!shellGlobalParams.authenticationMechanism.empty()) {
+ authStringStream << "DB.prototype._defaultAuthenticationMechanism = \"" <<
+ escape(shellGlobalParams.authenticationMechanism) << "\";" << endl;
+ }
+
+ if (!shellGlobalParams.gssapiServiceName.empty()) {
+ authStringStream << "DB.prototype._defaultGssapiServiceName = \"" <<
+ escape(shellGlobalParams.gssapiServiceName) << "\";" << endl;
+ }
+
+ if (!shellGlobalParams.nodb && shellGlobalParams.username.size()) {
+ authStringStream << "var username = \"" << escape(shellGlobalParams.username) << "\";" <<
+ endl;
+ if (shellGlobalParams.usingPassword) {
+ authStringStream << "var password = \"" << escape(shellGlobalParams.password) << "\";"
+ << endl;
+ }
+ if (shellGlobalParams.authenticationDatabase.empty()) {
+ authStringStream << "var authDb = db;" << endl;
+ }
+ else {
+ authStringStream << "var authDb = db.getSiblingDB(\""
+ << escape(shellGlobalParams.authenticationDatabase) << "\");" << endl;
+ }
+ authStringStream << "authDb._authOrThrow({ " <<
+ saslCommandUserFieldName << ": username ";
+ if (shellGlobalParams.usingPassword) {
+ authStringStream << ", " << saslCommandPasswordFieldName << ": password ";
}
- authStringStream << "}())";
- mongo::shell_utils::_dbAuth = authStringStream.str();
+ if (!shellGlobalParams.gssapiHostName.empty()) {
+ authStringStream << ", " << saslCommandServiceHostnameFieldName << ": \""
+ << escape(shellGlobalParams.gssapiHostName) << '"' << endl;
+ }
+ authStringStream << "});" << endl;
}
+ authStringStream << "}())";
+ mongo::shell_utils::_dbAuth = authStringStream.str();
mongo::ScriptEngine::setConnectCallback( mongo::shell_utils::onConnect );
mongo::ScriptEngine::setup();
@@ -852,44 +738,68 @@ int _main( int argc, char* argv[], char **envp ) {
auto_ptr< mongo::Scope > scope( mongo::globalScriptEngine->newScope() );
shellMainScope = scope.get();
- if( runShell )
+ if( shellGlobalParams.runShell )
cout << "type \"help\" for help" << endl;
+
+ // Load and execute /etc/mongorc.js before starting shell
+ std::string rcGlobalLocation;
+#ifndef _WIN32
+ rcGlobalLocation = "/etc/mongorc.js" ;
+#else
+ wchar_t programDataPath[MAX_PATH];
+ if ( S_OK == SHGetFolderPathW(NULL,
+ CSIDL_COMMON_APPDATA,
+ NULL,
+ 0,
+ programDataPath) ) {
+ rcGlobalLocation = str::stream() << toUtf8String(programDataPath)
+ << "\\MongoDB\\mongorc.js";
+ }
+#endif
+ if ( !rcGlobalLocation.empty() && ::mongo::shell_utils::fileExists(rcGlobalLocation) ) {
+ if ( ! scope->execFile( rcGlobalLocation , false , true ) ) {
+ cout << "The \"" << rcGlobalLocation << "\" file could not be executed" << endl;
+ }
+ }
- if ( !script.empty() ) {
+ if ( !shellGlobalParams.script.empty() ) {
mongo::shell_utils::MongoProgramScope s;
- if ( ! scope->exec( script , "(shell eval)" , true , true , false ) )
+ if ( ! scope->exec( shellGlobalParams.script , "(shell eval)" , true , true , false ) )
return -4;
}
- for (size_t i = 0; i < files.size(); ++i) {
+ for (size_t i = 0; i < shellGlobalParams.files.size(); ++i) {
mongo::shell_utils::MongoProgramScope s;
- if ( files.size() > 1 )
- cout << "loading file: " << files[i] << endl;
+ if ( shellGlobalParams.files.size() > 1 )
+ cout << "loading file: " << shellGlobalParams.files[i] << endl;
- if ( ! scope->execFile( files[i] , false , true , false ) ) {
- cout << "failed to load: " << files[i] << endl;
+ if ( ! scope->execFile( shellGlobalParams.files[i] , false , true ) ) {
+ cout << "failed to load: " << shellGlobalParams.files[i] << endl;
return -3;
}
}
- if ( files.size() == 0 && script.empty() )
- runShell = true;
+ if ( shellGlobalParams.files.size() == 0 && shellGlobalParams.script.empty() )
+ shellGlobalParams.runShell = true;
- if ( runShell ) {
+ if ( shellGlobalParams.runShell ) {
mongo::shell_utils::MongoProgramScope s;
- bool hasMongoRC = norc; // If they specify norc, assume it's not their first time
+ // If they specify norc, assume it's not their first time
+ bool hasMongoRC = shellGlobalParams.norc;
string rcLocation;
- if ( !norc ) {
+ if ( !shellGlobalParams.norc ) {
#ifndef _WIN32
if ( getenv( "HOME" ) != NULL )
rcLocation = str::stream() << getenv( "HOME" ) << "/.mongorc.js" ;
#else
if ( getenv( "HOMEDRIVE" ) != NULL && getenv( "HOMEPATH" ) != NULL )
- rcLocation = str::stream() << getenv( "HOMEDRIVE" ) << getenv( "HOMEPATH" ) << "\\.mongorc.js";
+ rcLocation = str::stream() << toUtf8String(_wgetenv(L"HOMEDRIVE"))
+ << toUtf8String(_wgetenv(L"HOMEPATH"))
+ << "\\.mongorc.js";
#endif
- if ( !rcLocation.empty() && fileExists(rcLocation) ) {
+ if ( !rcLocation.empty() && ::mongo::shell_utils::fileExists(rcLocation) ) {
hasMongoRC = true;
if ( ! scope->execFile( rcLocation , false , true ) ) {
cout << "The \".mongorc.js\" file located in your home folder could not be executed" << endl;
@@ -899,16 +809,15 @@ int _main( int argc, char* argv[], char **envp ) {
}
if ( !hasMongoRC && isatty(fileno(stdin)) ) {
- cout << "Welcome to the MongoDB shell.\n"
- "For interactive help, type \"help\".\n"
- "For more comprehensive documentation, see\n\thttp://docs.mongodb.org/\n"
- "Questions? Try the support group\n\thttp://groups.google.com/group/mongodb-user" << endl;
- fstream f;
- f.open(rcLocation.c_str(), ios_base::out );
- f.close();
+ cout << "Welcome to the MongoDB shell.\n"
+ "For interactive help, type \"help\".\n"
+ "For more comprehensive documentation, see\n\thttp://docs.mongodb.org/\n"
+ "Questions? Try the support group\n\thttp://groups.google.com/group/mongodb-user" << endl;
+ File f;
+ f.open(rcLocation.c_str(), false); // Create empty .mongorc.js file
}
- if ( !nodb && !mongo::cmdLine.quiet && isatty(fileno(stdin)) ) {
+ if (!shellGlobalParams.nodb && !mongo::serverGlobalParams.quiet && isatty(fileno(stdin))) {
scope->exec( "shellHelper( 'show', 'startupWarnings' )", "(shellwarnings", false, true, false );
}
@@ -932,7 +841,7 @@ int _main( int argc, char* argv[], char **envp ) {
else if ( ( promptType == Code ) &&
execPrompt( *scope, "prompt", prompt ) ) {
}
- else if ( execPrompt( *scope, "replSetMemberStatePrompt", prompt ) ) {
+ else if ( execPrompt( *scope, "defaultPrompt", prompt ) ) {
}
else {
prompt = "> ";
@@ -950,7 +859,7 @@ int _main( int argc, char* argv[], char **envp ) {
}
if ( ! linePtr || ( strlen( linePtr ) == 4 && strstr( linePtr , "exit" ) ) ) {
- if ( ! mongo::cmdLine.quiet )
+ if (!mongo::serverGlobalParams.quiet)
cout << "bye" << endl;
if ( line )
free( line );
@@ -1036,17 +945,20 @@ int _main( int argc, char* argv[], char **envp ) {
shellHistoryDone();
}
- mongo::dbexitCalled = true;
+ {
+ mongo::mutex::scoped_lock lk(mongo::shell_utils::mongoProgramOutputMutex);
+ mongo::dbexitCalled = true;
+ }
return 0;
}
#ifdef _WIN32
-int wmain( int argc, wchar_t* argvW[] ) {
+int wmain(int argc, wchar_t* argvW[], wchar_t* envpW[]) {
static mongo::StaticObserver staticObserver;
int returnCode;
try {
- WindowsCommandLine wcl( argc, argvW );
- returnCode = _main( argc, wcl.argv(), NULL ); // TODO: Convert wide env to utf8 env.
+ WindowsCommandLine wcl(argc, argvW, envpW);
+ returnCode = _main(argc, wcl.argv(), wcl.envp());
}
catch ( mongo::DBException& e ) {
cerr << "exception: " << e.what() << endl;