00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <sys/wait.h>
00019 #include <getopt.h>
00020 #include <iostream>
00021 #include <execinfo.h>
00022
00023 using namespace std;
00024
00025 #ifdef USE_QT
00026 #include <qapplication.h>
00027
00028 #include "RioQt.h"
00029 #endif
00030 #include "RioShell.h"
00031 #include "RioError.h"
00032
00033
00034
00035
00036 #ifdef USE_QT
00037 static RioQt *rioqt;
00038 #endif
00039 static RioShell *rioshell;
00040
00041
00042
00043
00044 void Usage( char* );
00045 #ifdef USE_QT
00046 void handle_SIGCHLD( int );
00047 #endif
00048 void handle_SIGINT( int );
00049
00050
00051
00052
00053 void Usage( char *progname )
00054 {
00055 #ifdef USE_QT
00056 cout << "\nUsage: " << progname
00057 << " -s <server_name> -u <user_name> [-p <password>] [-t | -t -o] -c \"command [-]\"\n";
00058 #else
00059 cout << "\nUsage: " << progname
00060 << " -s <server_name> -u <user_name> [-p <password>] [-o] -c \"command [-]\"\n";
00061 #endif
00062
00063 cout << "Options:" << endl;
00064 cout << "-s|--server <server_name>: Log in to server 'server_name'." << endl;
00065 cout << "-u|--user <user_name>: Log in using the user name 'user_name'." << endl;
00066
00067 #ifdef USE_QT
00068 cout << "-t|--text-mode: Log in using the user name user_name." << endl;
00069 cout << "-o|--clean-output: Just output the commands results. Only valid with -t" << endl;
00070 cout << "-p|--password: User Password. Only valid with -t" << endl;
00071 cout << "-c|--command \"command\": Execute command 'command' on the server and exit. Only valid with -t" << endl;
00072 cout << "-: Pass commands to riosh through a pipe. Only valid with -t" << endl;
00073 #else
00074 cout << "-o|--clean-output: Just output the commands results." << endl;
00075 cout << "-p|--password: User Password." << endl;
00076 cout << "-c|--command \"command\": Execute command 'command' on the server and exit." << endl;
00077 cout << "-: Pass commands to riosh through a pipe." << endl;
00078 #endif
00079 }
00080
00081
00082
00083
00084 void show_stackframe()
00085 {
00086 void *trace[16];
00087 char **messages = (char **)NULL;
00088 int i, trace_size = 0;
00089
00090 trace_size = backtrace( trace, 16 );
00091 messages = backtrace_symbols( trace, trace_size );
00092 RioErr << "[bt] Execution path:" << endl;
00093 for( i = 0; i < trace_size; ++i )
00094 RioErr << "[bt(" << i << "/" << trace_size << ")] " << messages[i]
00095 << endl;
00096 }
00097
00098 void segfaultHandler( int sig )
00099 {
00100 RioErr << "[Riosh-main] SEGMENTATION FAULT!" << endl;
00101 show_stackframe();
00102
00103 _exit( 1 );
00104 }
00105
00106 int main( int argc, char *argv[] )
00107 {
00108 char *UserName = NULL;
00109 char *MachineName = NULL;
00110 char *Password = NULL;
00111 bool commandMode = false;
00112
00113 #ifdef USE_QT
00114 bool textMode = false;
00115 #endif
00116
00117 char *cmdLine1 = NULL;
00118 bool stdOut = false;
00119 bool pipe_mode = false;
00120
00121 char optch;
00122 int ind = -1;
00123 int status;
00124
00125 #ifdef USE_QT
00126 static char opts_short[] = "c:hp:os:tu:v";
00127 #else
00128 static char opts_short[] = "c:hp:os:u:v";
00129 #endif
00130
00131 static struct option opts_int[] =
00132 {
00133 {"command" ,1,0,'c'},
00134 {"help" ,0,0,'h'},
00135 {"clean-output" ,0,0,'o'},
00136 {"server" ,1,0,'s'},
00137
00138 #ifdef USE_QT
00139 {"text-mode" ,0,0,'t'},
00140 #endif
00141
00142 {"user" ,1,0,'u'},
00143 {"password" ,1,0,'p'},
00144 {"version" ,0,0,'v'},
00145 {0,0,0,0}
00146 };
00147
00148 signal( SIGSEGV, segfaultHandler );
00149
00150 while( ( optch = getopt_long( argc, argv, opts_short, opts_int, &ind ) ) != -1 )
00151 {
00152 switch( optch )
00153 {
00154 case 'o':
00155 stdOut = true;
00156 break;
00157
00158 case 's':
00159 if( MachineName == NULL )
00160 MachineName = strdup( optarg );
00161 break;
00162
00163 #ifdef USE_QT
00164 case 't':
00165 textMode = true;
00166 break;
00167 #endif
00168
00169 case 'u':
00170 if( UserName == NULL )
00171 UserName = strdup( optarg );
00172 break;
00173
00174 case 'c':
00175 commandMode = true;
00176 cmdLine1 = strdup( optarg );
00177 break;
00178
00179 case 'p':
00180 Password = strdup( optarg );
00181 if( strlen( Password ) > MAXPASSWORDSIZE )
00182 {
00183 cout << argv[ 0 ] << ": password too long!" << endl;
00184 exit( -1 );
00185 }
00186 break;
00187
00188 case 'v':
00189 cout << "riosh version: " << VERSION << endl;
00190 exit( 0 );
00191
00192 case 'h':
00193 Usage( argv[ 0 ] );
00194 return( 0 );
00195
00196 default:
00197 Usage( argv[ 0 ] );
00198 return( -1 );
00199 }
00200 }
00201
00202
00203
00204
00205 if( strcmp( argv[argc - 1], "-" ) == 0 )
00206 {
00207 pipe_mode = true;
00208 }
00209
00210 if( !pipe_mode && ( argc - optind > 0 ) )
00211 {
00212 int i, length;
00213 commandMode = true;
00214 length = 0;
00215
00216 for( i = optind; i < argc; i++ )
00217 length = strlen( argv[ i ] );
00218
00219 cmdLine1 = (char *)malloc( ( length + ( argc - optind ) + 2 )
00220 * sizeof( char ) );
00221 for( i = optind; i < argc; i++ )
00222 {
00223 strcpy( cmdLine1 + strlen( cmdLine1 ), argv[ i ] );
00224 strcat( cmdLine1, " " );
00225 }
00226
00227 cmdLine1[ strlen( cmdLine1 ) - 1 ] = 0;
00228 }
00229 if( pipe_mode && ( argc - optind > 1 ) )
00230 {
00231 int i, length;
00232 commandMode = true;
00233 length = 0;
00234
00235 for( i = optind; i < argc - 1; i++ )
00236 length = strlen( argv[ i ] );
00237
00238 cmdLine1 = (char *)malloc( ( length + ( argc - optind ) + 1 )
00239 * sizeof( char ) );
00240 for( i = optind; i < argc - 1; i++ )
00241 {
00242 strcpy( cmdLine1 + strlen( cmdLine1 ), argv[ i ] );
00243 strcat( cmdLine1, " " );
00244 }
00245
00246 cmdLine1[ strlen( cmdLine1 ) - 1 ] = 0;
00247 }
00248
00249 #ifdef USE_QT
00250
00251 if( ( stdOut || commandMode || pipe_mode || ( Password != NULL ) ) &&
00252 ! textMode )
00253 Usage( argv[ 0 ] );
00254
00255
00256 if( !textMode )
00257 {
00258 QApplication app( argc, argv );
00259
00260
00261 signal( SIGCHLD, handle_SIGCHLD );
00262 rioqt = new RioQt();
00263 app.setMainWidget( rioqt );
00264
00265 return app.exec();
00266 }
00267 else
00268 {
00269
00270 for( int i = 1; i < argc; i++ )
00271 {
00272 if( strcmp( argv[i], "--password" ) == 0 ||
00273 strcmp( argv[i], "-p" ) == 0 )
00274 {
00275 int len = strlen( argv[i + 1] );
00276 for( int j = 0; j < len; j++ )
00277 argv[i + 1][j] = '*';
00278 }
00279 }
00280
00281 rioshell = new RioShell( MachineName, UserName, Password );
00282 if( rioshell->connect() )
00283 {
00284 signal( SIGINT, handle_SIGINT );
00285 status = rioshell->exec( commandMode, stdOut, cmdLine1, pipe_mode );
00286 delete rioshell;
00287 return status;
00288 }
00289 else
00290 {
00291 return RIOSHELL_ERROR;
00292 }
00293 }
00294 #else
00295
00296 for( int i = 1; i < argc; i++ )
00297 {
00298 if( strcmp( argv[i], "--password" ) == 0 ||
00299 strcmp( argv[i], "-p" ) == 0 )
00300 {
00301 int len = strlen( argv[i + 1] );
00302 for( int j = 0; j < len; j++ )
00303 argv[i + 1][j] = '*';
00304 }
00305 }
00306
00307 rioshell = new RioShell( MachineName, UserName, Password );
00308 if( rioshell->connect() )
00309 {
00310 signal( SIGINT, handle_SIGINT );
00311 status = rioshell->exec( commandMode, stdOut, cmdLine1, pipe_mode );
00312 delete rioshell;
00313 return status;
00314 }
00315 else
00316 {
00317 return RIOSHELL_ERROR;
00318 }
00319 #endif
00320
00321 return 0;
00322 }
00323
00324 #ifdef USE_QT
00325
00326
00327
00328 void handle_SIGCHLD( int )
00329 {
00330 int data, status;
00331
00332 data = waitpid( -1, &status, WNOHANG );
00333
00334
00335 if( data > 0 )
00336 {
00337 rioqt->handle_SIGCHLD( data, WEXITSTATUS( status ) );
00338 }
00339 }
00340 #endif
00341
00342
00343
00344
00345 void handle_SIGINT( int )
00346 {
00347 rioshell->handle_SIGINT( );
00348 }
00349