Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:13.1:Update
xorg-x11-Xvnc
Xvnc.pl
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File Xvnc.pl of Package xorg-x11-Xvnc
#!/usr/bin/perl # Emulate Xvnc by starting x11vnc inside Xvfb # (c) 2011 Matthias Hopf <mhopf@suse.de> # For a number of additional pitfalls see http://www.karlrunge.com/x11vnc/faq.html#faq-xvfb # TODO: # - authorization with -query # - choose a fresh display with -inetd use POSIX(); use POSIX ":sys_wait_h"; use IO::Handle; # # Option parsing # @cmd_x11 = ("/usr/bin/Xvfb"); @cmd_vnc = ("/usr/bin/x11vnc"); $display = ""; $geometry = "800x600"; $depth = 24; $rfbport = ""; $httpdir = ""; $auth = ""; $inetd = 0; # Preparse options for -inetd (logfile generation) for $_ (@ARGV) { $inetd = 1 if $_ eq "-inetd"; } # Logfile generation for -inetd if ($inetd) { $logfile = $ENV{HOME}."/.Xvnc.log"; $logfile = "/var/log/Xvnc.log" if $> == 0; unlink "$logfile.old"; rename $logfile, "$logfile.old"; close STDERR; unless (open STDERR, '>', $logfile) { chomp ($logfile=`mktemp /tmp/Xvnc.XXXXXXXXXX`); unless (open STDERR, '>', $logfile) { unless (open STDERR, '>', "/dev/null") { die; } } } STDERR->autoflush(1); chmod 0600, $logfile; STDOUT->autoflush(1); } while ($_ = shift @ARGV) { # Special handling if (/^:/) { $display = $_; } elsif ($_ eq "-auth") { $auth = shift @ARGV; } elsif ($_ eq "-geometry") { $geometry = shift @ARGV; } elsif ($_ eq "-depth") { $depth = shift @ARGV; } elsif ($_ eq "-rfbport") { $rfbport = shift @ARGV; } elsif ($_ eq "-httpd") { $httpdir = shift @ARGV; } elsif ($_ eq "-inetd") { } # Pure x11vnc options elsif ($_ eq "-loginauth") { push @cmd_vnc, "-unixpw"; } elsif ($_ eq "-rfbwait") { push @cmd_vnc, "-timeout", ((shift @ARGV) + 999) / 1000; } elsif ($_ eq "-interface") { push @cmd_vnc, "-listen", shift @ARGV; } # Direct pure x11vnc options elsif (/^(-viewonly|-localhost|-nocursor|-alwaysshared|-nevershared|-dontdisconnect)$/) { push @cmd_vnc, $_; } # Direct pure x11vnc options with 1 argument elsif (/^(-desktop|-rfbauth|-deferupdate|-httpport)$/) { push @cmd_vnc, $_, shift @ARGV; } # Direct pure Xserver options elsif (/^(-ac|-br|\+bs|-bs|-c|-core|-dpms|-I|-nolock|-logo|nologo|-noreset|-nr|-reset|-pn|-nopn|-r|r|ttyxx|v|-tst|-v|-wm|-wr|-maxbigreqsize|\+xinerama|-xinerama|-dumbSched|-retro|-terminate|-broadcast|-once|-ardelay|-arinterval)$/) { push @cmd_x11, $_; } # Direct pure Xserver options with 1 argument elsif (/^(-a|-audit|c|-cc|-dpi|-deferglyphs|-f|-fc|-fn|-fp|-ld|-lf|-ls|-nolisten|-p|-s|-t|-to|-schedInterval|\+extension|-extension|-query|-indirect|-port|-from|-class|-cookie|-displayID)$/) { push @cmd_x11, $_, shift @ARGV; } # Ignore following options for now elsif (/^(-economictranslate|-lazytight)$/) { } # Ignore following options for now with 1 argument elsif (/^(-pixelformat)$/) { shift; } # Currently unsupported elsif (/^(-render|-multicast|[+-]accessx)$/) { # -render [default|mono|gray|color] set render color alloc policy # There is -render <arg> of Xvnc *and* -render of Xvfb w/o arg... # -multicast [addr [hops]] IPv6 multicast for XDMCP # Difficult option parsing, no use with Xvnc # [+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ] # enable/disable accessx key sequences # Difficult option parsing, gdm overwrites opts anyway # -udpinputport port UDP port for keyboard/pointer data # Unknown how to support print STDERR "Xvnc option $_ currently unsupported!\n"; exit 1; } else { print STDERR <<"EOHELP"; use: Xvnc [:<display>] [option] -a # default pointer acceleration (factor) -ac disable access control restrictions -audit int set audit trail level -auth file select authorization file -br create root window with black background +bs enable any backing store support -bs disable any backing store support -c turns off key-click c # key-click volume (0-100) -cc int default color visual class -nocursor disable the cursor -core generate core dump on fatal error -dpi int screen resolution in dots per inch -dpms disables VESA DPMS monitor control -deferglyphs [none|all|16] defer loading of [no|all|16-bit] glyphs -f # bell base (0-100) -fc string cursor font -fn string default font name -fp string default font path -help prints message with these options -I ignore all remaining arguments -ld int limit data space to N Kb -lf int limit number of open files to N -ls int limit stack space to N Kb -nolock disable the locking mechanism -logo enable logo in screen saver nologo disable logo in screen saver -nolisten string don't listen on protocol -noreset don't reset after last client exists -nr create root window with no background -reset reset after last client exists -p # screen-saver pattern duration (minutes) -pn accept failure to listen on all ports -nopn reject failure to listen on all ports -r turns off auto-repeat r turns on auto-repeat -render [default|mono|gray|color] set render color alloc policy -retro start with classic stipple and cursor -s # screen-saver timeout (minutes) -t # default pointer threshold (pixels/t) -terminate terminate at server reset -to # connection time out -tst disable testing extensions ttyxx server started from init on /dev/ttyxx v video blanking for screen-saver -v screen-saver without video blanking -wm WhenMapped default backing-store -wr create root window with white background -maxbigreqsize set maximal bigrequest size +xinerama Enable XINERAMA extension -xinerama Disable XINERAMA extension -dumbSched Disable smart scheduling, enable old behavior -schedInterval int Set scheduler interval in msec +extension name Enable extension -extension name Disable extension -query host-name contact named host for XDMCP -broadcast broadcast for XDMCP -multicast [addr [hops]] IPv6 multicast for XDMCP -indirect host-name contact named host for indirect XDMCP -port port-num UDP port number to send messages to -from local-address specify the local address to connect from -once Terminate server after one session -class display-class specify display class to send in manage -cookie xdm-auth-bits specify the magic cookie for XDMCP -displayID display-id manufacturer display ID for request [+-]accessx [ timeout [ timeout_mask [ feedback [ options_mask] ] ] ] enable/disable accessx key sequences -ardelay set XKB autorepeat delay -arinterval set XKB autorepeat interval -geometry WxH set framebuffer width & height -depth D set framebuffer depth -pixelformat format set pixel format (BGRnnn or RGBnnn) -udpinputport port UDP port for keyboard/pointer data -rfbport port TCP port for RFB protocol -rfbwait time max time in ms to wait for RFB client -nocursor don't put up a cursor -rfbauth passwd-file use authentication on RFB protocol -loginauth use login-style Unix authentication -httpd dir serve files via HTTP from here -httpport port port for HTTP -deferupdate time time in ms to defer updates (default 40) -economictranslate less memory-hungry translation -lazytight disable "gradient" filter in tight encoding -desktop name VNC desktop name (default x11) -alwaysshared always treat new clients as shared -nevershared never treat new clients as shared -dontdisconnect don't disconnect existing clients when a new non-shared connection comes in (refuse new connection instead) -localhost only allow connections from localhost to the vnc ports. Use -nolisten tcp to disable remote X clients as well. -viewonly let clients only view the desktop -interface ipaddr only bind to specified interface address -inetd Xvnc is launched by inetd EOHELP exit 1; } } # # Command line generation # push @cmd_x11, "-screen", "0", "$geometry"."x$depth"; push @cmd_x11, "-cc", "4" if $depth > 8; if ($inetd) { push @cmd_vnc, "-inetd" if $inetd; } else { push @cmd_vnc, $rfbport eq "" ? ("-N") : ("-rfbport", $rfbport); push @cmd_vnc, $httpdir eq "" ? ("-http") : ("-httpdir", $httpdir); # -threads doesn't work with -inetd?!? push @cmd_vnc, "-shared", "-threads"; } if ($auth ne "") { push @cmd_x11, "-auth", $auth; push @cmd_vnc, "-auth", $auth; } push @cmd_vnc, "-norc", "-forever"; push @cmd_vnc, "-cursor_drag", "-scrollcopyrect", "always", "-nowireframe"; #-env FD_XDM=1 # Multi-keyboard corrections ?!? push @cmd_vnc, "-skip_lockkeys", "-add_keysyms", "-clear_all"; push @cmd_x11, $display; push @cmd_vnc, "-display", $display; # # Process startup preparation # $ret = 0; $pid_x11 = 0; $pid_vnc = 0; $pid_pip = 0; $got_usr1= 0; $got_usr2= 0; $orig_usr1 = $SIG{USR1}; # Wait for any process, and check for known processes # Args: nonblock(1) sub waitall { my $id; if ($_[0]) { $id = waitpid (-1, WNOHANG); } else { $id = wait (); } if ($id > 0 && $ret == 0 && $? != 0) { $ret = ($? >> 8); $ret = 255 if $? < 256; } $pid_x11 = 0 if $id == $pid_x11; $pid_vnc = 0 if $id == $pid_vnc; $pid_pip = 0 if $id == $pid_pip; return $id; } # Terminate all subprocesses sub terminate { # Wait for all processes to actually end by themselves eval { alarm 2; while ($pid_x11 > 0 || $pid_vnc > 0 || $pid_pip > 0) { last if waitall (0) < 0; } alarm 0; }; # Terminate both main processes kill QUIT, $pid_x11 if $pid_x11 > 0; kill QUIT, $pid_vnc if $pid_vnc > 0; # Wait for both processes to actually end eval { alarm 5; while ($pid_x11 > 0 || $pid_vnc > 0 || $pid_pip > 0) { last if waitall (0) < 0; } alarm 0; }; # Kill leftover processes kill KILL, $pid_x11 if $pid_x11 > 0; kill KILL, $pid_vnc if $pid_vnc > 0; kill KILL, $pid_pip if $pid_pip > 0; } sub END { terminate(); } # Signal handler sub sig_exit { terminate(); $SIG{$_[0]} = "DEFAULT"; kill $_[0], $$; } sub sig_alrm { $SIG{ALRM} = \&sig_alrm; die; } sub sig_usr1 { $SIG{USR1} = \&sig_usr1; $got_usr1++; } sub sig_usr2 { $SIG{USR2} = \&sig_usr2; $got_usr2++; } # Set signal handlers for cleanup for $s (HUP, INT, QUIT, TERM) { $SIG{$s} = \&sig_exit; } $SIG{ALRM} = \&sig_alrm; $SIG{PIPE} = "IGNORE"; # Set signal handlers for IPC $SIG{USR1} = \&sig_usr1; $SIG{USR2} = \&sig_usr2; # # Process startup # eval { alarm 30; # Start Xserver print STDERR "* Starting up Xserver\n* ".join (" ", @cmd_x11)."\n"; $pid_x11 = fork(); die "fork failed: $!" unless defined $pid_x11; if (! $pid_x11) { # Redirect stdout into stderr (for handling inetd) close STDOUT; open STDOUT, ">&STDERR"; close STDIN; # Ignore USR1 to indicate Xserver to ping us when ready $SIG{USR1}="IGNORE"; #exec "/usr/bin/Xvfb", "-screen", "0", "800x600x24", ":4"; exec @cmd_x11; die "Starting Xvfb"; } # Wait for Xserver to either finish startup, or being killed my $retries=10; while ($retries > 0 && !$got_usr1) { last if waitall (1) > 0; sleep 1; $retries--; } exit $ret if !$pid_x11; exit 1 if !$got_usr1; # Create stdout pipe for vnc server pipe R, W; # Start vnc server print STDERR "* Starting up vnc server\n* ".join (" ", @cmd_vnc)."\n"; $pid_vnc = fork(); die "fork failed: $!" unless defined $pid_vnc; if (! $pid_vnc) { # Don't terminate X server inside child if dying here $pid_x11=0; # Redirect stderr into pipe close R; close STDERR; open STDERR, ">&W"; close W; #exec "/usr/bin/x11vnc", "-N", "-display", ":4"; exec @cmd_vnc; die "Starting x11vnc"; } close W; # Start process for parsing vnc output $pid_pip = fork(); die "fork failed: $!" unless defined $pid_pip; if (! $pid_pip) { close STDIN; close STDOUT; while (<R>) { print STDERR "vnc: $_"; kill USR2, getppid() if /^[0-9\/: ]*screen setup finished\.\s*$/; } exit 0; } close R; # Wait for vnc server being ready my $retries=10; while ($retries > 0 && !$got_usr2) { last if waitall (1) > 0; sleep 1; $retries--; } exit $ret if !$pid_vnc; exit 1 if !$got_usr2; alarm 0; }; print STDERR "* All up and running\n"; # Ping parent if it wants to get informed about us being ready kill USR1, getppid() if $orig_usr1 eq "IGNORE"; # # Wait for shutdown # # Wait for one of the processes to terminate while ($pid_x11 > 0 && $pid_vnc > 0 && $pid_pip > 0) { last if waitall (0) < 0; } exit $ret;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor