// (c) 2012 Timothy Pearson
// (c) 2012 Raptor Engineering
// ALL RIGHTS RESERVED
# define _GNU_SOURCE
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <stdarg.h>
# include <limits.h>
# include <netdb.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <arpa/inet.h>
# include <pwd.h>
# include <grp.h>
# include <time.h>
# include <mysql/mysql.h>
# include "libraptorsmiface.h"
# define STATISTICS_SERVER_START_EVENT 0
# define STATISTICS_SERVER_STOP_EVENT 1
# define STATISTICS_NEW_CONNECTION_EVENT 2
# define STATISTICS_CONNECTION_STATUS_EVENT 3
# define STATISTICS_DISCONNECTION_EVENT 4
//char *server = "localhost";
char * server = " freyja.starlink.edu " ;
char * user = " remotelab " ;
char * password = " rlpass123 " ; /* set me first */
char * database = " remotelab_sm " ;
void dprint ( const char * fmt , . . . )
{
va_list argp ;
va_start ( argp , fmt ) ;
#if 0
vprintf ( fmt , argp ) ;
# else
char debug [ 512 ] ;
vsprintf ( debug , fmt , argp ) ;
FILE * fp = fopen ( " /raptorsmiface.debug " , " a " ) ;
if ( fp ! = NULL )
{
fputs ( debug , fp ) ;
fclose ( fp ) ;
}
# endif
va_end ( argp ) ;
}
MYSQL * connect_if_needed ( ) {
MYSQL * conn = mysql_init ( NULL ) ;
if ( ! mysql_real_connect ( conn , server , user , password , database , 0 , NULL , 0 ) ) {
dprint ( " [ERROR] MySQL connection FAILED [%s] \n \r " , mysql_error ( conn ) ) ;
conn = 0 ;
}
return conn ;
}
char * get_mysql_escaped_string ( MYSQL * sqlcn , char * rawstr ) {
unsigned int minlen = strlen ( rawstr ) ;
unsigned int maxlen = ( ( minlen * 2 ) + 1 ) ;
char * escstr = malloc ( maxlen * sizeof ( char ) ) ;
mysql_real_escape_string ( sqlcn , escstr , rawstr , minlen ) ;
return escstr ;
}
char mutex ;
int mysql_query_internal ( MYSQL * conn , const char * query ) {
// For some reason this can hang rather badly
// It might be related to concurrent access to the same conn object though
return mysql_query ( conn , query ) ;
}
char * get_group_for_user ( char * username ) {
struct passwd * pwd ;
pwd = getpwnam ( username ) ;
if ( ! pwd ) {
return true ;
}
gid_t groupid = pwd - > pw_gid ;
struct group * primarygroup ;
primarygroup = getgrgid ( groupid ) ;
if ( ! primarygroup ) {
return true ;
}
return strdup ( primarygroup - > gr_name ) ;
}
char raptor_sm_deallocate_session ( char * username ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
MYSQL_RES * svr_res ;
MYSQL_ROW svr_row ;
MYSQL_RES * cnt_res ;
MYSQL_ROW cnt_row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return 1 ;
}
int display = raptor_sm_get_display_for_username ( username ) ;
char * hostname = raptor_sm_get_hostname_for_username ( username , false ) ;
pid_t serverpid = raptor_sm_get_pid_for_username ( username , RAPTOR_SM_SERVER_PID_FIELD ) ;
if ( serverpid > = 0 ) {
// Verify non-existence of PID on remote server before removing session information from the database
char * ip = raptor_sm_get_ip_for_hostname ( hostname , 0 ) ;
char * command_string ;
asprintf ( & command_string , " ssh root@%s \' ps -p %d | grep %d \' " , ip , serverpid , serverpid ) ;
FILE * fp ;
char output [ 1024 ] ;
// Open the command for reading
fp = popen ( command_string , " r " ) ;
if ( fp = = NULL ) {
mysql_close ( conn ) ;
return - 1 ;
}
// Read the output a line at a time
fgets ( output , sizeof ( output ) - 1 , fp ) ;
// Close output
pclose ( fp ) ;
free ( command_string ) ;
free ( ip ) ;
if ( strcmp ( output , " " ) ! = 0 ) {
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
// Remove the user from the system
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " DELETE FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( hostname ) ;
free ( query ) ;
mysql_close ( conn ) ;
return 2 ;
}
else {
free ( query ) ;
// Insert connection information into the statistics database
char * safe_servername = get_mysql_escaped_string ( conn , hostname ) ;
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
long long timestamp = time ( NULL ) ;
asprintf ( & query , " INSERT INTO statistics (timestamp, eventtypeid, servername, display, typeid, username) VALUES ('%lld', '%d', '%s', '%d', '%d', '%s') " , timestamp , STATISTICS_DISCONNECTION_EVENT , safe_servername , display , - 1 , safe_username ) ;
free ( safe_servername ) ;
free ( safe_username ) ;
free ( hostname ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
dprint ( " Unable to insert data into statistics database! [%s] \n \r " , mysql_error ( conn ) ) ;
}
free ( query ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
char * raptor_sm_allocate_session ( char * username ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
MYSQL_RES * svr_res ;
MYSQL_ROW svr_row ;
MYSQL_RES * per_res ;
MYSQL_ROW per_row ;
MYSQL_RES * cnt_res ;
MYSQL_ROW cnt_row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return strdup ( " ERROR " ) ;
}
// Verify that this user is not already on the system
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT servername FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( " ERROR " ) ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
if ( ( row = mysql_fetch_row ( res ) ) = = NULL ) {
// User is not on a system
// Find the least utilized node
if ( mysql_query_internal ( conn , " SELECT name FROM servers WHERE online='1' " ) ) {
// Server error
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return strdup ( " ERROR " ) ;
}
else {
svr_res = mysql_store_result ( conn ) ;
// Get group for user
char * groupname = get_group_for_user ( username ) ;
char * safe_groupname = get_mysql_escaped_string ( conn , groupname ) ;
free ( groupname ) ;
// Get the list of allowed nodes for this group
asprintf ( & query , " SELECT server FROM allowed_servers WHERE groupname='%s' " , safe_groupname ) ;
free ( safe_groupname ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
mysql_free_result ( res ) ;
mysql_free_result ( svr_res ) ;
mysql_close ( conn ) ;
return strdup ( " ERROR " ) ;
}
else {
per_res = mysql_store_result ( conn ) ;
char * bestserver = strdup ( " " ) ;
int bestusage = INT_MAX ;
while ( ( svr_row = mysql_fetch_row ( svr_res ) ) ! = NULL ) {
// Am I allowed to use this server?
bool can_use_server = false ;
while ( ( per_row = mysql_fetch_row ( per_res ) ) ! = NULL ) {
if ( strcmp ( per_row [ 0 ] , svr_row [ 0 ] ) = = 0 ) {
can_use_server = true ;
}
}
mysql_data_seek ( per_res , 0 ) ;
if ( can_use_server ) {
char * safe_servername = get_mysql_escaped_string ( conn , svr_row [ 0 ] ) ;
asprintf ( & query , " SELECT username FROM sessions WHERE servername='%s' " , safe_servername ) ;
free ( safe_servername ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
free ( bestserver ) ;
mysql_free_result ( res ) ;
mysql_free_result ( svr_res ) ;
mysql_close ( conn ) ;
return strdup ( " ERROR " ) ;
}
else {
free ( query ) ;
cnt_res = mysql_store_result ( conn ) ;
int usagecount = 0 ;
while ( ( cnt_row = mysql_fetch_row ( cnt_res ) ) ! = NULL ) {
usagecount + + ;
}
mysql_free_result ( cnt_res ) ;
if ( usagecount < bestusage ) {
free ( bestserver ) ;
bestserver = strdup ( svr_row [ 0 ] ) ;
bestusage = usagecount ;
}
}
}
}
mysql_free_result ( res ) ;
mysql_free_result ( svr_res ) ;
mysql_free_result ( per_res ) ;
if ( strcmp ( bestserver , " " ) ! = 0 ) {
// Insert new information into the sessions database and set status to ALLOCATED
char * safe_servername = get_mysql_escaped_string ( conn , bestserver ) ;
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " INSERT INTO sessions (username, servername, state) VALUES ('%s', '%s', '%d') " , safe_username , safe_servername , SM_STATUS_ALLOCATED ) ;
free ( safe_servername ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( " ERROR " ) ;
}
else {
free ( query ) ;
// Insert connection information into the statistics database
char * safe_servername = get_mysql_escaped_string ( conn , bestserver ) ;
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
long long timestamp = time ( NULL ) ;
asprintf ( & query , " INSERT INTO statistics (timestamp, eventtypeid, servername, display, typeid, username) VALUES ('%lld', '%d', '%s', '%d', '%d', '%s') " , timestamp , STATISTICS_NEW_CONNECTION_EVENT , safe_servername , - 1 , SM_STATUS_ALLOCATED , safe_username ) ;
free ( safe_servername ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
dprint ( " Unable to insert data into statistics database! [%s] \n \r " , mysql_error ( conn ) ) ;
}
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( bestserver ) ;
}
}
else {
// No usable server found!
mysql_close ( conn ) ;
return strdup ( " ERROR " ) ;
}
}
}
}
else {
char * ret = strdup ( row [ 0 ] ) ;
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
}
}
char * raptor_sm_get_ip_for_hostname ( char * hostname , char * error ) {
struct addrinfo hints , * res ;
struct in_addr addr ;
int err ;
memset ( & hints , 0 , sizeof ( hints ) ) ;
hints . ai_socktype = SOCK_STREAM ;
hints . ai_family = AF_INET ;
if ( ( err = getaddrinfo ( hostname , NULL , & hints , & res ) ) ! = 0 ) {
if ( error ) * error = 1 ;
return strdup ( " " ) ;
}
addr . s_addr = ( ( struct sockaddr_in * ) ( res - > ai_addr ) ) - > sin_addr . s_addr ;
char * ret = strdup ( inet_ntoa ( addr ) ) ;
freeaddrinfo ( res ) ;
if ( error ) * error = 0 ;
return ret ;
}
char * raptor_sm_get_hostname_for_username ( char * username , bool create ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return strdup ( " SQLERR100 " ) ;
}
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT servername FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( " SQLERR101 " ) ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
char * ret = strdup ( row [ 0 ] ) ;
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
// Nothing in the DB
mysql_free_result ( res ) ;
if ( create ) {
// Try to allocate a new session on a node
mysql_close ( conn ) ;
return raptor_sm_allocate_session ( username ) ;
}
else {
mysql_close ( conn ) ;
return strdup ( " " ) ;
}
}
}
char * raptor_sm_get_hostname_for_display ( int display ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return strdup ( " SQLERR100 " ) ;
}
asprintf ( & query , " SELECT servername FROM sessions WHERE display='%d' " , display ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( " SQLERR101 " ) ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
char * ret = strdup ( row [ 0 ] ) ;
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
// Nothing in the DB
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return strdup ( " " ) ;
}
}
char * raptor_sm_get_ip_for_username ( char * username , bool create ) {
char * hostname = raptor_sm_get_hostname_for_username ( username , create ) ;
char err ;
char * ip = raptor_sm_get_ip_for_hostname ( hostname , & err ) ;
free ( hostname ) ;
if ( err ) {
raptor_sm_deallocate_session ( username ) ;
return strdup ( " ERROR " ) ;
}
return ip ;
}
bool raptor_sm_sesslimit_reached ( char * username ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return true ;
}
// Respect maximum session number for the group for this user
int sesslimit = 0 ; // Default to denying all sessions
// Get group for user
char * groupname = get_group_for_user ( username ) ;
char * safe_groupname = get_mysql_escaped_string ( conn , groupname ) ;
free ( groupname ) ;
asprintf ( & query , " SELECT sesslimit FROM groups WHERE groupname='%s' " , safe_groupname ) ;
free ( safe_groupname ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return true ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
row = mysql_fetch_row ( res ) ;
if ( row [ 0 ] ) {
sesslimit = atoi ( row [ 0 ] ) ;
}
mysql_free_result ( res ) ;
}
// Figure out how many users are online from this group
int sesscount = 0 ;
asprintf ( & query , " SELECT username FROM sessions WHERE state<>'%d' " , SM_STATUS_ALLOCATED ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return true ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
if ( row [ 0 ] ) {
char * test_groupname = get_group_for_user ( row [ 0 ] ) ;
if ( strcmp ( groupname , test_groupname ) = = 0 ) {
sesscount + + ;
}
free ( test_groupname ) ;
}
}
mysql_free_result ( res ) ;
if ( sesscount < sesslimit ) {
mysql_close ( conn ) ;
return false ;
}
mysql_close ( conn ) ;
return true ;
}
// We should never end up here!
mysql_close ( conn ) ;
return true ;
}
pid_t raptor_sm_run_remote_server ( char * username , char * const argv [ ] , char * dbfield , int display ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
if ( strcmp ( dbfield , RAPTOR_SM_SERVER_PID_FIELD ) = = 0 ) {
// Respect maximum session number for the group for this user
if ( raptor_sm_sesslimit_reached ( username ) ) {
mysql_close ( conn ) ;
return - 5 ;
}
}
// Make sure a server is not already running for this user
// Return the existing PID if it is
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
if ( strcmp ( dbfield , RAPTOR_SM_SERVER_PID_FIELD ) = = 0 ) {
asprintf ( & query , " SELECT %s,servername FROM sessions WHERE username='%s' AND state<>'%d' " , dbfield , safe_username , SM_STATUS_ALLOCATED ) ;
}
else {
asprintf ( & query , " SELECT %s,servername FROM sessions WHERE username='%s' " , dbfield , safe_username ) ;
}
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
if ( row [ 0 ] ) {
int ret = atoi ( row [ 0 ] ) ;
if ( ret > = 0 ) {
// Verify existence of PID on remote server
dprint ( " Verifying process %d on %s... \n \r " , ret , row [ 1 ] ) ;
char * ip = raptor_sm_get_ip_for_hostname ( row [ 1 ] , 0 ) ;
char * command_string ;
asprintf ( & command_string , " ssh root@%s \' ps -p %d | grep %d \' " , ip , ret , ret ) ;
FILE * fp ;
char output [ 1024 ] ;
// Open the command for reading
fp = popen ( command_string , " r " ) ;
if ( fp = = NULL ) {
mysql_close ( conn ) ;
return - 1 ;
}
// Read the output a line at a time
fgets ( output , sizeof ( output ) - 1 , fp ) ;
// Close output
pclose ( fp ) ;
free ( command_string ) ;
free ( ip ) ;
dprint ( " ...result was %s \n \r " , output ) ;
if ( strcmp ( output , " " ) ! = 0 ) {
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
}
}
}
mysql_free_result ( res ) ;
}
int i ;
int n_commands ;
n_commands = 0 ;
while ( argv [ n_commands ] ! = NULL ) {
n_commands + + ;
}
char * ipaddr = raptor_sm_get_ip_for_username ( username , true ) ;
// This is HORRIBLY inefficient
char * command_string = strdup ( " " ) ;
for ( i = 0 ; i < n_commands ; i + + ) {
char * origstr = command_string ;
asprintf ( & command_string , " %s %s " , origstr , argv [ i ] ) ;
free ( origstr ) ;
}
char * origstr = command_string ;
# ifndef RAPTOR_SM_DISABLE_PULSEAUDIO
if ( display > = 0 ) {
asprintf ( & command_string , " ssh root@%s \" su %s -c \' export DISPLAY=:%d && export PULSE_SERVER=tcp:%s:%d && pulseaudio -D --load= \\ \" module-native-protocol-tcp listen=0.0.0.0 auth-ip-acl=%s port=%d \\ \" \' &> /dev/null \" & " , ipaddr , username , display , ipaddr , ( RAPTOR_SM_BASE_PULSEAUDIO_PORT + display ) , RAPTOR_SM_MANAGEMENT_SERVER_IP_NETRANGE , ( RAPTOR_SM_BASE_PULSEAUDIO_PORT + display ) ) ;
dprint ( " Running command %s... \n \r " , command_string ) ;
system ( command_string ) ;
}
# endif
if ( strcmp ( dbfield , RAPTOR_SM_SERVER_PID_FIELD ) = = 0 ) {
asprintf ( & command_string , " ssh root@%s \' %s & echo $! & \' " , ipaddr , origstr ) ;
}
else {
# if RAPTOR_SM_DISABLE_PULSEAUDIO
asprintf ( & command_string , " ssh root@%s \" su %s -c \' export DISPLAY=:%d && %s \' &> /dev/null & echo \\ $! \" " , ipaddr , username , display , origstr ) ;
# else
//asprintf(&command_string, "ssh root@%s \"su %s -c \'export DISPLAY=:%d && export PULSE_SERVER=tcp:%s:%d && %s\' &> /dev/null & echo \\$!\"", ipaddr, username, display, ipaddr, (RAPTOR_SM_BASE_PULSEAUDIO_PORT+display), origstr);
asprintf ( & command_string , " ssh root@%s \" su %s -c \' export DISPLAY=:%d && export PULSE_SERVER=tcp:%s:%d && %s \' &> /var/log/%s_wm_session.log & echo \\ $! \" " , ipaddr , username , display , ipaddr , ( RAPTOR_SM_BASE_PULSEAUDIO_PORT + display ) , origstr , username ) ;
# endif
}
dprint ( " Running command %s... \n \r " , command_string ) ;
free ( origstr ) ;
FILE * fp ;
char output [ 1024 ] ;
// Open the command for reading
fp = popen ( command_string , " r " ) ;
if ( fp = = NULL ) {
mysql_close ( conn ) ;
return - 1 ;
}
// Read the output a line at a time
fgets ( output , sizeof ( output ) - 1 , fp ) ;
// Close output
pclose ( fp ) ;
free ( command_string ) ;
mysql_close ( conn ) ;
return atoi ( output ) ;
}
pid_t raptor_sm_get_pid_for_username ( char * username , char * dbfield ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Make sure a server is not already running for this user
// Return the existing PID if it is
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT %s FROM sessions WHERE username='%s' " , dbfield , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
if ( row [ 0 ] ) {
int ret = atoi ( row [ 0 ] ) ;
if ( ret > = 0 ) {
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
}
}
mysql_free_result ( res ) ;
}
mysql_close ( conn ) ;
return - 3 ;
}
char * raptor_sm_server_started ( char * username , pid_t pid , int display , char * dbfield ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
long long timestamp = time ( NULL ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Update new information into the sessions database and set status to ALLOCATED
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " UPDATE sessions SET %s='%d', stamp_start='%lld', state='%d', display='%d', stamp_statechange='%lld' WHERE username='%s' AND state='%d' " , dbfield , pid , timestamp , SM_STATUS_RUNNING , display , timestamp , safe_username , SM_STATUS_ALLOCATED ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
// Insert connection information into the statistics database
char * current_server = raptor_sm_get_hostname_for_display ( display ) ;
char * safe_servername = get_mysql_escaped_string ( conn , current_server ) ;
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
long long timestamp = time ( NULL ) ;
asprintf ( & query , " INSERT INTO statistics (timestamp, eventtypeid, servername, display, typeid, username) VALUES ('%lld', '%d', '%s', '%d', '%d', '%s') " , timestamp , STATISTICS_CONNECTION_STATUS_EVENT , safe_servername , display , SM_STATUS_RUNNING , safe_username ) ;
free ( safe_servername ) ;
free ( safe_username ) ;
free ( current_server ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
dprint ( " Unable to insert data into statistics database! [%s] \n \r " , mysql_error ( conn ) ) ;
}
free ( query ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
char * raptor_sm_wm_started ( char * username , pid_t pid , char * dbfield ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Update new information into the sessions database and set status to ALLOCATED
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " UPDATE sessions SET %s='%d' WHERE username='%s' " , dbfield , pid , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
int raptor_sm_get_display_for_username ( char * username ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " SELECT display FROM sessions WHERE username='%s' " , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
if ( row [ 0 ] ) {
int ret = atoi ( row [ 0 ] ) ;
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
else {
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return - 3 ;
}
}
// Nothing in the DB
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return - 4 ;
}
}
char * raptor_sm_get_username_for_display_and_hostname ( int display , char * hostname ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
char * safe_hostname = get_mysql_escaped_string ( conn , hostname ) ;
asprintf ( & query , " SELECT username FROM sessions WHERE display='%d' AND servername='%s' " , display , safe_hostname ) ;
free ( safe_hostname ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return strdup ( " " ) ;
}
else {
free ( query ) ;
res = mysql_store_result ( conn ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
if ( row [ 0 ] ) {
char * ret = strdup ( row [ 0 ] ) ;
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return ret ;
}
else {
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return strdup ( " " ) ;
}
}
// Nothing in the DB
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return strdup ( " " ) ;
}
}
void raptor_sm_wait_for_pid_exit ( char * username , pid_t pid ) {
char * ipaddr = raptor_sm_get_ip_for_username ( username , false ) ;
char * command_string ;
asprintf ( & command_string , " ssh root@%s \' while [[ `ps -p %d | grep %d` != \" \" ]]; do sleep 1; done \' " , ipaddr , pid , pid ) ;
system ( command_string ) ;
free ( command_string ) ;
}
void raptor_sm_session_terminated ( char * username ) {
raptor_sm_deallocate_session ( username ) ;
}
void raptor_sm_wm_terminated ( char * username ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
long long timestamp = time ( NULL ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Update new information into the sessions database
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
asprintf ( & query , " UPDATE sessions SET %s=NULL WHERE username='%s' " , RAPTOR_SM_WM_PID_FIELD , safe_username ) ;
free ( safe_username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
int raptor_sm_get_new_unique_display ( int mindisplay , int maxdisplay ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
asprintf ( & query , " SELECT display FROM sessions " ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
dprint ( " [ERROR] MySQL connection FAILED [%s] \n \r " , mysql_error ( conn ) ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
res = mysql_store_result ( conn ) ;
int freedisp ;
bool dispinuse ;
for ( freedisp = mindisplay ; freedisp < maxdisplay ; freedisp + + ) {
dispinuse = false ;
mysql_data_seek ( res , 0 ) ;
while ( ( row = mysql_fetch_row ( res ) ) ! = NULL ) {
if ( row [ 0 ] ) {
if ( atoi ( row [ 0 ] ) = = freedisp ) {
dispinuse = true ;
}
}
}
if ( dispinuse = = false ) {
break ;
}
}
mysql_free_result ( res ) ;
mysql_close ( conn ) ;
return freedisp ;
}
}
char raptor_sm_set_session_state ( int display , int state ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
long long timestamp = time ( NULL ) ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Update new state into the sessions database
asprintf ( & query , " UPDATE sessions SET state='%d', stamp_statechange='%lld' WHERE display='%d' " , state , timestamp , display ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
free ( query ) ;
mysql_close ( conn ) ;
return - 2 ;
}
else {
free ( query ) ;
// Insert connection information into the statistics database
char * hostname = raptor_sm_get_hostname_for_display ( display ) ;
char * username = raptor_sm_get_username_for_display_and_hostname ( display , hostname ) ;
char * safe_servername = get_mysql_escaped_string ( conn , hostname ) ;
char * safe_username = get_mysql_escaped_string ( conn , username ) ;
long long timestamp = time ( NULL ) ;
asprintf ( & query , " INSERT INTO statistics (timestamp, eventtypeid, servername, display, typeid, username) VALUES ('%lld', '%d', '%s', '%d', '%d', '%s') " , timestamp , STATISTICS_CONNECTION_STATUS_EVENT , safe_servername , display , state , safe_username ) ;
free ( safe_servername ) ;
free ( safe_username ) ;
free ( hostname ) ;
free ( username ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
dprint ( " Unable to insert data into statistics database! [%s] \n \r " , mysql_error ( conn ) ) ;
}
free ( query ) ;
mysql_close ( conn ) ;
return 0 ;
}
}
void raptor_sm_run_remote_desktop ( char * username , int display , char * executable ) {
char * ipaddr = raptor_sm_get_ip_for_username ( username , true ) ;
char * command_string ;
# if RAPTOR_SM_DISABLE_PULSEAUDIO
asprintf ( & command_string , " ssh root@%s \" su %s -c \' export DISPLAY=:%d && %s && exit \' &> /dev/null \" " , ipaddr , username , display , executable ) ;
# else
asprintf ( & command_string , " ssh root@%s \" su %s -c \' export DISPLAY=:%d && export PULSE_SERVER=tcp:%s:%d && %s && exit \' &> /dev/null \" " , ipaddr , username , display , ipaddr , ( RAPTOR_SM_BASE_PULSEAUDIO_PORT + display ) , executable ) ;
# endif
system ( command_string ) ;
free ( command_string ) ;
}
void raptor_sm_terminate_server ( char * username ) {
char * ipaddr = raptor_sm_get_ip_for_username ( username , true ) ;
char * command_string ;
// Terminate remote X server
pid_t pid = raptor_sm_get_pid_for_username ( username , RAPTOR_SM_SERVER_PID_FIELD ) ;
if ( pid > 0 ) {
asprintf ( & command_string , " ssh root@%s \' kill -9 %ld \' " , ipaddr , pid ) ;
system ( command_string ) ;
free ( command_string ) ;
}
}
void raptor_sm_stats_report_server_start ( char * hostname ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Insert information into the statistics database
char * safe_servername = get_mysql_escaped_string ( conn , hostname ) ;
long long timestamp = time ( NULL ) ;
asprintf ( & query , " INSERT INTO statistics (timestamp, eventtypeid, servername, display, typeid) VALUES ('%lld', '%d', '%s', '%d', '%d') " , timestamp , STATISTICS_SERVER_START_EVENT , safe_servername , - 1 , - 1 ) ;
free ( safe_servername ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
dprint ( " Unable to insert data into statistics database! [%s] \n \r " , mysql_error ( conn ) ) ;
}
free ( query ) ;
mysql_close ( conn ) ;
}
void raptor_sm_stats_report_server_stop ( char * hostname ) {
MYSQL_RES * res ;
MYSQL_ROW row ;
char * query ;
MYSQL * conn = connect_if_needed ( ) ;
if ( ! conn ) {
return - 1 ;
}
// Insert information into the statistics database
char * safe_servername = get_mysql_escaped_string ( conn , hostname ) ;
long long timestamp = time ( NULL ) ;
asprintf ( & query , " INSERT INTO statistics (timestamp, eventtypeid, servername, display, typeid) VALUES ('%lld', '%d', '%s', '%d', '%d') " , timestamp , STATISTICS_SERVER_STOP_EVENT , safe_servername , - 1 , - 1 ) ;
free ( safe_servername ) ;
if ( mysql_query_internal ( conn , query ) ) {
// Server error
dprint ( " Unable to insert data into statistics database! [%s] \n \r " , mysql_error ( conn ) ) ;
}
free ( query ) ;
mysql_close ( conn ) ;
}