1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-06 00:13:33 +00:00

The following updates, fix KVM for openSUSE and other distros with similar behavior

1. Removed 'setDisplay()' because it doesn't work
2. Added more descriptive error message when XOpenDisplay fails
3. Added ability to set XAUTHORITY in the child process if it wasn't set, by finding how X was started
This commit is contained in:
Bryan Roe
2019-01-24 11:19:33 -08:00
parent bf6e9ce1e0
commit 559928de5b
4 changed files with 67 additions and 47 deletions

View File

@@ -231,29 +231,6 @@ int getNextDisplay() {
return 0;
}
int setDisplay(unsigned short display_no) {
char cmd[BUFSIZ] = "";
char authFile[BUFSIZ] = "";
FILE *pfile = NULL;
int dispNo;
sprintf(cmd, "ps aux 2>/dev/null | grep '/X.* :[0-9][0-9]* .*-auth' | egrep -v 'startx|xinit' | sed -e 's,^.*/X.* :\\([0-9][0-9]*\\) .* -auth \\([^ ][^ ]*\\).*$,\\1\\,\\2,' | grep '%d,'", display_no);
pfile = popen(cmd, "r");
if (pfile == NULL) {
return -1;
}
if (fscanf(pfile, "%d,%510s", &dispNo, authFile) != 2) {
fclose(pfile);
return -1;
}
fclose(pfile);
return setenv("XAUTHORITY", authFile, 1);
}
void kvm_send_display_list()
{
unsigned short *displays = NULL;
@@ -343,26 +320,26 @@ int kvm_init(int displayNo)
sprintf(displayString, ":%d", (int)displayNo);
while (setDisplay(displayNo) != 0 && count++ < 10);
if (count == 10) { return -1; }
count = 0;
eventdisplay = x11_exports->XOpenDisplay(displayString);
//fprintf(logFile, "XAUTHORITY is %s", getenv("XAUTHORITY")); fflush(logFile);
if (eventdisplay == NULL)
{
char tmpBuff[1024];
sprintf_s(tmpBuff, sizeof(tmpBuff), "XOpenDisplay(%s) failed, using XAUTHORITY: %s", displayString, getenv("XAUTHORITY"));
//fprintf(logFile, "DisplayString=%s\n", displayString);
//fprintf(logFile, "XAUTHORITY is %s", getenv("XAUTHORITY")); fflush(logFile);
//fprintf(logFile, "Error calling XOpenDisplay()\n"); fflush(logFile);
kvm_send_error("Error occured calling XOpenDisplay()");
kvm_send_error(tmpBuff);
}
if (eventdisplay != NULL) { current_display = (unsigned short)displayNo; }
while (eventdisplay == NULL && count++ < 100) {
while (eventdisplay == NULL && count++ < 100)
{
if (getNextDisplay() == -1) { return -1; }
sprintf(displayString, ":%d", (int)current_display);
if (setDisplay(current_display) != 0) { continue; }
eventdisplay = x11_exports->XOpenDisplay(displayString);
}
@@ -608,8 +585,6 @@ void* kvm_server_mainloop(void* parm)
CheckDesktopSwitch(1);
//fprintf(logFile, "After CheckDesktopSwitch.\n"); fflush(logFile);
setDisplay(current_display);
sprintf(displayString, ":%d", (int)current_display);
imagedisplay = x11_exports->XOpenDisplay(displayString);
@@ -756,7 +731,7 @@ void kvm_relay_readSink(ILibProcessPipe_Pipe sender, char *buffer, int bufferLen
}
*bytesConsumed = 0;
}
void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid)
void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid, char* authToken)
{
int r;
int count = 0;
@@ -794,6 +769,10 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w
if (uid != 0) { ignore_result(setuid(uid)); }
//fprintf(logFile, "Starting kvm_server_mainloop\n");
if (authToken != NULL)
{
setenv("XAUTHORITY", authToken, 1);
}
kvm_server_mainloop((void*)0);
return(NULL);
}
@@ -810,11 +789,11 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w
// Setup the KVM session. Return 1 if ok, 0 if it could not be setup.
void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid)
void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid, char *authToken)
{
if (kvmthread != (pthread_t)NULL || g_slavekvm != 0) return 0;
g_restartcount = 0;
return kvm_relay_restart(1, processPipeMgr, writeHandler, reserved, uid);
return kvm_relay_restart(1, processPipeMgr, writeHandler, reserved, uid, authToken);
}
// Force a KVM reset & refresh

View File

@@ -40,7 +40,7 @@ typedef ILibTransport_DoneState(*ILibKVM_WriteHandler)(char *buffer, int bufferL
void kvm_set_x11_locations(char *libx11, char *libx11tst, char *libx11ext);
int kvm_relay_feeddata(char* buf, int len);
void kvm_pause(int pause);
void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid);
void* kvm_relay_setup(void *processPipeMgr, ILibKVM_WriteHandler writeHandler, void *reserved, int uid, char *authToken);
void kvm_relay_reset();
void kvm_cleanup();

View File

@@ -1248,7 +1248,39 @@ duk_ret_t ILibDuktape_MeshAgent_getRemoteDesktop(duk_context *ctx)
ptrs->kvmPipe = kvm_relay_setup(agent->exePath, agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs, console_uid);
}
#else
ptrs->kvmPipe = kvm_relay_setup(agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs, console_uid);
// For Linux, we need to determine where the XAUTHORITY is:
char *updateXAuth = NULL;
int needPop = 0;
if (getenv("XAUTHORITY") == NULL)
{
if (duk_peval_string(ctx, "(function getAuthToken()\
{\
var child = require('child_process').execFile('/bin/sh', ['sh']);\
child.stdout.str = '';\
child.stdin.write('ps -e -o user -o command | awk {\\'printf \"%s,\",$1;$1=\"\";printf \"%s\\\\n\", $0\\'} | grep X\\nexit\\n');\
child.stdout.on('data', function(chunk) { this.str += chunk.toString(); });\
child.waitExit();\
var lines = child.stdout.str.split('\\n');\
for (var i in lines) {\
var tokens = lines[i].split(',');\
if (tokens[0]) {\
var items = tokens[1].split(' ');\
for (var x = 0; x < items.length; ++x) {\
if (items[x] == '-auth' && items.length >(x + 1)) {\
return (items[x + 1]);\
}\
}\
}\
}\
return (null);\
})();") == 0)
{
updateXAuth = (char*)duk_get_string(ctx, -1);
}
needPop = 1;
}
ptrs->kvmPipe = kvm_relay_setup(agent->pipeManager, ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink, ptrs, console_uid, updateXAuth);
if (needPop!= 0) {duk_pop(ctx); }
#endif
#endif
return 1;

View File

@@ -1,16 +1,25 @@
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdin.write('ps -e -o user -o command | awk {\'printf "%s,",$1;$1="";printf "%s\\n", $0\'} | grep X\nexit\n');
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.waitExit();
var lines = child.stdout.str.split('\n');
for (var i in lines)
function getAuthToken()
{
var tokens = lines[i].split(',');
console.log(tokens[0] + ' => ' + tokens[1]);
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = '';
child.stdin.write('ps -e -o user -o command | awk {\'printf "%s,",$1;$1="";printf "%s\\n", $0\'} | grep X\nexit\n');
child.stdout.on('data', function (chunk) { this.str += chunk.toString(); });
child.waitExit();
var lines = child.stdout.str.split('\n');
for (var i in lines) {
var tokens = lines[i].split(',');
if (tokens[0]) {
var items = tokens[1].split(' ');
for (var x = 0; x < items.length; ++x) {
if (items[x] == '-auth' && items.length > (x + 1)) {
return (items[x + 1]);
}
}
}
}
return (null);
}
//console.log(child.stdout.str);
console.log('AuthToken => ' + getAuthToken());
process.exit();