From 0311365810f11b1db8bc6a01bfc5ab95ee241ba8 Mon Sep 17 00:00:00 2001 From: Keith Winstein Date: Fri, 28 Sep 2012 20:06:04 -0400 Subject: [PATCH] Read utmpx directly instead of using "who", and prettify detached warning --- configure.ac | 1 + src/frontend/mosh-server.cc | 63 ++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 33 deletions(-) diff --git a/configure.ac b/configure.ac index d3622c1..f233575 100644 --- a/configure.ac +++ b/configure.ac @@ -180,6 +180,7 @@ AC_CHECK_HEADERS([arpa/inet.h fcntl.h langinfo.h limits.h locale.h netinet/in.h AC_CHECK_HEADERS([pty.h util.h libutil.h paths.h]) AC_CHECK_HEADERS([endian.h sys/endian.h]) +AC_CHECK_HEADERS([utmpx.h]) # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL diff --git a/src/frontend/mosh-server.cc b/src/frontend/mosh-server.cc index 965d67a..e3f6714 100644 --- a/src/frontend/mosh-server.cc +++ b/src/frontend/mosh-server.cc @@ -55,6 +55,10 @@ #include #include +#ifdef HAVE_UTMPX_H +#include +#endif + #ifdef HAVE_PATHS_H #include #endif @@ -104,7 +108,7 @@ void print_usage( const char *argv0 ) void print_motd( void ); void chdir_homedir( void ); bool motd_hushed( void ); -void warn_unattached( const char *ignore_entry ); +void warn_unattached( const string & ignore_entry ); /* Simple spinloop */ void spin( void ) @@ -779,8 +783,9 @@ string mosh_read_line( FILE *file ) return ret; } -void warn_unattached( const char *ignore_entry ) +void warn_unattached( const string & ignore_entry ) { +#ifdef HAVE_UTMPX_H /* get username */ const struct passwd *pw = getpwuid( geteuid() ); if ( pw == NULL ) { @@ -792,45 +797,37 @@ void warn_unattached( const char *ignore_entry ) const string username( pw->pw_name ); /* look for unattached sessions */ - FILE *who_cmd = popen( "who", "r" ); + vector< string > unattached_mosh_servers; - if ( who_cmd == NULL ) { - return; - } - - vector< string > unattached_who_lines; - - while ( !feof( who_cmd ) ) { - /* read the line */ - const string line = mosh_read_line( who_cmd ); - - /* does line start with username? */ - if ( line.substr( 0, username.size() + 1 ) == username + " " ) { - /* does line show unattached mosh session? */ - if ( line.npos != line.find( "(mosh" ) ) { - /* is line showing _this_ mosh session? */ - const string our_entry = string( "(" ) + ignore_entry + string( ")" ); - if ( line.npos == line.find( our_entry ) ) { - unattached_who_lines.push_back( line ); - } + while ( struct utmpx *entry = getutxent() ) { + if ( (entry->ut_type == USER_PROCESS) + && (username == string( entry->ut_user )) ) { + /* does line show unattached mosh session */ + string text( entry->ut_host ); + if ( (text.substr( 0, 5 ) == "mosh ") + && (text != ignore_entry) ) { + unattached_mosh_servers.push_back( text ); } } } /* print out warning if necessary */ - if ( unattached_who_lines.empty() ) { + if ( unattached_mosh_servers.empty() ) { return; - } else if ( unattached_who_lines.size() == 1 ) { - printf( "\nNote: This Mosh server is detached.\n" ); + } else if ( unattached_mosh_servers.size() == 1 ) { + printf( "\033[37;44mMosh: You have a detached Mosh session on this server (%s).\033[m\n\n", + unattached_mosh_servers.front().c_str() ); } else { - printf( "\nNote: These Mosh servers are detached.\n" ); - } + string pid_string; - for ( vector< string >::const_iterator it = unattached_who_lines.begin(); - it != unattached_who_lines.end(); - it++ ) { - printf( "| %s\n", it->c_str() ); - } + for ( vector< string >::const_iterator it = unattached_mosh_servers.begin(); + it != unattached_mosh_servers.end(); + it++ ) { + pid_string += " - " + *it + "\n"; + } - printf( "\n" ); + printf( "\033[37;44mMosh: You have %d detached Mosh sessions on this server, with PIDs:\n%s\033[m\n", + (int)unattached_mosh_servers.size(), pid_string.c_str() ); + } +#endif /* HAVE_UTMPX_H */ }