Read utmpx directly instead of using "who", and prettify detached warning

This commit is contained in:
Keith Winstein
2012-09-28 20:06:04 -04:00
parent 9ac3b65090
commit 0311365810
2 changed files with 31 additions and 33 deletions
+1
View File
@@ -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([pty.h util.h libutil.h paths.h])
AC_CHECK_HEADERS([endian.h sys/endian.h]) AC_CHECK_HEADERS([endian.h sys/endian.h])
AC_CHECK_HEADERS([utmpx.h])
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL AC_HEADER_STDBOOL
+28 -31
View File
@@ -55,6 +55,10 @@
#include <time.h> #include <time.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#endif
#ifdef HAVE_PATHS_H #ifdef HAVE_PATHS_H
#include <paths.h> #include <paths.h>
#endif #endif
@@ -104,7 +108,7 @@ void print_usage( const char *argv0 )
void print_motd( void ); void print_motd( void );
void chdir_homedir( void ); void chdir_homedir( void );
bool motd_hushed( void ); bool motd_hushed( void );
void warn_unattached( const char *ignore_entry ); void warn_unattached( const string & ignore_entry );
/* Simple spinloop */ /* Simple spinloop */
void spin( void ) void spin( void )
@@ -779,8 +783,9 @@ string mosh_read_line( FILE *file )
return ret; return ret;
} }
void warn_unattached( const char *ignore_entry ) void warn_unattached( const string & ignore_entry )
{ {
#ifdef HAVE_UTMPX_H
/* get username */ /* get username */
const struct passwd *pw = getpwuid( geteuid() ); const struct passwd *pw = getpwuid( geteuid() );
if ( pw == NULL ) { if ( pw == NULL ) {
@@ -792,45 +797,37 @@ void warn_unattached( const char *ignore_entry )
const string username( pw->pw_name ); const string username( pw->pw_name );
/* look for unattached sessions */ /* look for unattached sessions */
FILE *who_cmd = popen( "who", "r" ); vector< string > unattached_mosh_servers;
if ( who_cmd == NULL ) { while ( struct utmpx *entry = getutxent() ) {
return; if ( (entry->ut_type == USER_PROCESS)
} && (username == string( entry->ut_user )) ) {
/* does line show unattached mosh session */
vector< string > unattached_who_lines; string text( entry->ut_host );
if ( (text.substr( 0, 5 ) == "mosh ")
while ( !feof( who_cmd ) ) { && (text != ignore_entry) ) {
/* read the line */ unattached_mosh_servers.push_back( text );
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 );
}
} }
} }
} }
/* print out warning if necessary */ /* print out warning if necessary */
if ( unattached_who_lines.empty() ) { if ( unattached_mosh_servers.empty() ) {
return; return;
} else if ( unattached_who_lines.size() == 1 ) { } else if ( unattached_mosh_servers.size() == 1 ) {
printf( "\nNote: This Mosh server is detached.\n" ); 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 { } else {
printf( "\nNote: These Mosh servers are detached.\n" ); string pid_string;
}
for ( vector< string >::const_iterator it = unattached_who_lines.begin(); for ( vector< string >::const_iterator it = unattached_mosh_servers.begin();
it != unattached_who_lines.end(); it != unattached_mosh_servers.end();
it++ ) { it++ ) {
printf( "| %s\n", it->c_str() ); 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 */
} }