You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

vncserver 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. #!/usr/bin/env perl
  2. #
  3. # Copyright (C) 2015-2019 Pierre Ossman for Cendio AB
  4. # Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved.
  5. # Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
  6. # Copyright (C) 2002-2003 Constantin Kaplinsky. All Rights Reserved.
  7. # Copyright (C) 2002-2005 RealVNC Ltd.
  8. # Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
  9. #
  10. # This is free software; you can redistribute it and/or modify
  11. # it under the terms of the GNU General Public License as published by
  12. # the Free Software Foundation; either version 2 of the License, or
  13. # (at your option) any later version.
  14. #
  15. # This software is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. # GNU General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU General Public License
  21. # along with this software; if not, write to the Free Software
  22. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  23. # USA.
  24. #
  25. #
  26. # vncserver - wrapper script to start an X VNC server.
  27. #
  28. # First make sure we're operating in a sane environment.
  29. $exedir = "";
  30. $slashndx = rindex($0, "/");
  31. if($slashndx>=0) {
  32. $exedir = substr($0, 0, $slashndx+1);
  33. }
  34. &SanityCheck();
  35. #
  36. # Global variables. You may want to configure some of these for
  37. # your site
  38. #
  39. $vncUserDir = "$ENV{HOME}/.vnc";
  40. $vncUserConfig = "$vncUserDir/config";
  41. $vncSystemConfigDir = "/etc/tigervnc";
  42. $vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults";
  43. $vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory";
  44. $skipxstartup = 0;
  45. $xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority";
  46. $xstartupFile = $vncUserDir . "/xstartup";
  47. $defaultXStartup
  48. = ("#!/bin/sh\n\n".
  49. "OS=`uname -s`\n".
  50. "if [ \$OS = 'Linux' ]; then\n".
  51. " case \"\$WINDOWMANAGER\" in\n".
  52. " \*gnome\*)\n".
  53. " if [ -e /etc/SuSE-release ]; then\n".
  54. " PATH=\$PATH:/opt/gnome/bin\n".
  55. " export PATH\n".
  56. " fi\n".
  57. " ;;\n".
  58. " esac\n".
  59. "fi\n".
  60. "if [ -x /etc/X11/xinit/xinitrc ]; then\n".
  61. " exec /etc/X11/xinit/xinitrc\n".
  62. "fi\n".
  63. "if [ -f /etc/X11/xinit/xinitrc ]; then\n".
  64. " exec sh /etc/X11/xinit/xinitrc\n".
  65. "fi\n".
  66. "[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n".
  67. "xsetroot -solid grey\n".
  68. "xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n".
  69. "twm\n");
  70. chop($host = `uname -n`);
  71. if (-d "/etc/X11/fontpath.d") {
  72. $fontPath = "catalogue:/etc/X11/fontpath.d";
  73. }
  74. @fontpaths = ('/usr/share/X11/fonts', '/usr/share/fonts', '/usr/share/fonts/X11/');
  75. if (! -l "/usr/lib/X11") {push(@fontpaths, '/usr/lib/X11/fonts');}
  76. if (! -l "/usr/X11") {push(@fontpaths, '/usr/X11/lib/X11/fonts');}
  77. if (! -l "/usr/X11R6") {push(@fontpaths, '/usr/X11R6/lib/X11/fonts');}
  78. push(@fontpaths, '/usr/share/fonts/default');
  79. @fonttypes = ('misc',
  80. '75dpi',
  81. '100dpi',
  82. 'Speedo',
  83. 'Type1');
  84. foreach $_fpath (@fontpaths) {
  85. foreach $_ftype (@fonttypes) {
  86. if (-f "$_fpath/$_ftype/fonts.dir") {
  87. if (! -l "$_fpath/$_ftype") {
  88. $defFontPath .= "$_fpath/$_ftype,";
  89. }
  90. }
  91. }
  92. }
  93. if ($defFontPath) {
  94. if (substr($defFontPath, -1, 1) == ',') {
  95. chop $defFontPath;
  96. }
  97. }
  98. if ($fontPath eq "") {
  99. $fontPath = $defFontPath;
  100. }
  101. # Check command line options
  102. &ParseOptions("-kill",1,"-help",0,"-h",0,"--help",0,"-list",0,
  103. "-fg",0,"-autokill",0,"-noxstartup",0,"-xstartup",1);
  104. &Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'});
  105. &Kill() if ($opt{'-kill'});
  106. &List() if ($opt{'-list'});
  107. if ($opt{'-noxstartup'}) {
  108. $skipxstartup = 1;
  109. }
  110. if ($opt{'-xstartup'}) {
  111. $xstartupFile = $opt{'-xstartup'};
  112. }
  113. # Create the user's vnc directory if necessary.
  114. if (!(-e $vncUserDir)) {
  115. if (!mkdir($vncUserDir,0755)) {
  116. die "$prog: Could not create $vncUserDir.\n";
  117. }
  118. }
  119. # Find display number.
  120. if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) {
  121. $displayNumber = $1;
  122. shift(@ARGV);
  123. if (!&CheckDisplayNumber($displayNumber)) {
  124. die "A VNC server is already running as :$displayNumber\n";
  125. }
  126. } elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) {
  127. &Usage();
  128. } else {
  129. $displayNumber = &GetDisplayNumber();
  130. }
  131. $vncPort = 5900 + $displayNumber;
  132. $desktopName = "$host:$displayNumber ($ENV{USER})";
  133. my %default_opts;
  134. my %config;
  135. # We set some reasonable defaults. Config file settings
  136. # override these where present.
  137. $default_opts{desktop} = &quotedString($desktopName);
  138. $default_opts{auth} = &quotedString($xauthorityFile);
  139. $default_opts{rfbwait} = 30000;
  140. $default_opts{rfbauth} = "$vncUserDir/passwd";
  141. $default_opts{rfbport} = $vncPort;
  142. $default_opts{fp} = $fontPath if ($fontPath);
  143. $default_opts{pn} = "";
  144. # Load user-overrideable system defaults
  145. LoadConfig($vncSystemConfigDefaultsFile);
  146. # Then the user's settings
  147. LoadConfig($vncUserConfig);
  148. # And then override anything set above if mandatory settings exist.
  149. # WARNING: "Mandatory" is used loosely here! As the man page says,
  150. # there is nothing stopping someone from EASILY subverting the
  151. # settings in $vncSystemConfigMandatoryFile by simply passing
  152. # CLI args to vncserver, which trump config files! To properly
  153. # hard force policy in a non-subvertible way would require major
  154. # development work that touches Xvnc itself.
  155. LoadConfig($vncSystemConfigMandatoryFile, 1);
  156. #
  157. # Check whether VNC authentication is enabled, and if so, prompt the user to
  158. # create a VNC password if they don't already have one.
  159. #
  160. $securityTypeArgSpecified = 0;
  161. $vncAuthEnabled = 0;
  162. $passwordArgSpecified = 0;
  163. @vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc");
  164. # ...first we check our configuration files' settings
  165. if ($config{'securitytypes'}) {
  166. $securityTypeArgSpecified = 1;
  167. foreach $arg2 (split(',', $config{'securitytypes'})) {
  168. if (grep {$_ eq lc($arg2)} @vncAuthStrings) {
  169. $vncAuthEnabled = 1;
  170. }
  171. }
  172. }
  173. if ($config{'password'} ||
  174. $config{'passwordfile'} ||
  175. $config{'rfbauth'}) {
  176. $passwordArgSpecified = 1;
  177. }
  178. if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) {
  179. ($z,$z,$mode) = stat("$vncUserDir/passwd");
  180. if (!(-e "$vncUserDir/passwd") || ($mode & 077)) {
  181. warn "\nYou will require a password to access your desktops.\n\n";
  182. system($exedir."vncpasswd -q $vncUserDir/passwd");
  183. if (($? >> 8) != 0) {
  184. exit 1;
  185. }
  186. }
  187. }
  188. $desktopLog = "$vncUserDir/$host:$displayNumber.log";
  189. unlink($desktopLog);
  190. # Make an X server cookie and set up the Xauthority file
  191. # mcookie is a part of util-linux, usually only GNU/Linux systems have it.
  192. $cookie = `mcookie`;
  193. # Fallback for non GNU/Linux OS - use /dev/urandom on systems that have it,
  194. # otherwise use perl's random number generator, seeded with the sum
  195. # of the current time, our PID and part of the encrypted form of the password.
  196. if ($cookie eq "" && open(URANDOM, '<', '/dev/urandom')) {
  197. my $randata;
  198. if (sysread(URANDOM, $randata, 16) == 16) {
  199. $cookie = unpack 'h*', $randata;
  200. }
  201. close(URANDOM);
  202. }
  203. if ($cookie eq "") {
  204. srand(time+$$+unpack("L",`cat $vncUserDir/passwd`));
  205. for (1..16) {
  206. $cookie .= sprintf("%02x", int(rand(256)) % 256);
  207. }
  208. }
  209. open(XAUTH, "|xauth -f $xauthorityFile source -");
  210. print XAUTH "add $host:$displayNumber . $cookie\n";
  211. print XAUTH "add $host/unix:$displayNumber . $cookie\n";
  212. close(XAUTH);
  213. # Now start the X VNC Server
  214. # We build up our Xvnc command with options
  215. $cmd = $exedir."Xvnc :$displayNumber";
  216. foreach my $k (sort keys %config) {
  217. $cmd .= " -$k $config{$k}";
  218. delete $default_opts{$k}; # file options take precedence
  219. }
  220. foreach my $k (sort keys %default_opts) {
  221. $cmd .= " -$k $default_opts{$k}";
  222. }
  223. # Run $cmd and record the process ID.
  224. $pidFile = "$vncUserDir/$host:$displayNumber.pid";
  225. system("$cmd & echo \$! >$pidFile");
  226. # Give Xvnc a chance to start up
  227. sleep(3);
  228. if ($fontPath ne $defFontPath) {
  229. unless (kill 0, `cat $pidFile`) {
  230. if ($fpArgSpecified) {
  231. warn "\nWARNING: The first attempt to start Xvnc failed, probably because the font\n";
  232. warn "path you specified using the -fp argument is incorrect. Attempting to\n";
  233. warn "determine an appropriate font path for this system and restart Xvnc using\n";
  234. warn "that font path ...\n";
  235. } else {
  236. warn "\nWARNING: The first attempt to start Xvnc failed, possibly because the font\n";
  237. warn "catalog is not properly configured. Attempting to determine an appropriate\n";
  238. warn "font path for this system and restart Xvnc using that font path ...\n";
  239. }
  240. $cmd =~ s@-fp [^ ]+@@;
  241. $cmd .= " -fp $defFontPath" if ($defFontPath);
  242. system("$cmd & echo \$! >$pidFile");
  243. sleep(3);
  244. }
  245. }
  246. unless (kill 0, `cat $pidFile`) {
  247. warn "Could not start Xvnc.\n\n";
  248. unlink $pidFile;
  249. open(LOG, "<$desktopLog");
  250. while (<LOG>) { print; }
  251. close(LOG);
  252. die "\n";
  253. }
  254. warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n";
  255. # Create the user's xstartup script if necessary.
  256. if (! $skipxstartup) {
  257. if (!(-e "$xstartupFile")) {
  258. warn "Creating default startup script $xstartupFile\n";
  259. open(XSTARTUP, ">$xstartupFile");
  260. print XSTARTUP $defaultXStartup;
  261. close(XSTARTUP);
  262. chmod 0755, "$xstartupFile";
  263. }
  264. }
  265. # Run the X startup script.
  266. if (! $skipxstartup) {
  267. warn "Starting applications specified in $xstartupFile\n";
  268. }
  269. warn "Log file is $desktopLog\n\n";
  270. # If the unix domain socket exists then use that (DISPLAY=:n) otherwise use
  271. # TCP (DISPLAY=host:n)
  272. if (-e "/tmp/.X11-unix/X$displayNumber" ||
  273. -e "/usr/spool/sockets/X11/$displayNumber")
  274. {
  275. $ENV{DISPLAY}= ":$displayNumber";
  276. } else {
  277. $ENV{DISPLAY}= "$host:$displayNumber";
  278. }
  279. $ENV{VNCDESKTOP}= $desktopName;
  280. if ($opt{'-fg'}) {
  281. if (! $skipxstartup) {
  282. system("$xstartupFile >> " . &quotedString($desktopLog) . " 2>&1");
  283. }
  284. if (kill 0, `cat $pidFile`) {
  285. $opt{'-kill'} = ':'.$displayNumber;
  286. &Kill();
  287. }
  288. } else {
  289. if ($opt{'-autokill'}) {
  290. if (! $skipxstartup) {
  291. system("($xstartupFile; $0 -kill :$displayNumber) >> "
  292. . &quotedString($desktopLog) . " 2>&1 &");
  293. }
  294. } else {
  295. if (! $skipxstartup) {
  296. system("$xstartupFile >> " . &quotedString($desktopLog)
  297. . " 2>&1 &");
  298. }
  299. }
  300. }
  301. exit;
  302. ###############################################################################
  303. # Functions
  304. ###############################################################################
  305. #
  306. # Populate the global %config hash with settings from a specified
  307. # vncserver configuration file if it exists
  308. #
  309. # Args: 1. file path
  310. # 2. optional boolean flag to enable warning when a previously
  311. # set configuration setting is being overridden
  312. #
  313. sub LoadConfig {
  314. local ($configFile, $warnoverride) = @_;
  315. local ($toggle) = undef;
  316. if (stat($configFile)) {
  317. if (open(IN, $configFile)) {
  318. while (<IN>) {
  319. next if /^#/;
  320. if (my ($k, $v) = /^\s*(\w+)\s*=\s*(.+)$/) {
  321. $k = lc($k); # must normalize key case
  322. if ($warnoverride && $config{$k}) {
  323. print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n");
  324. }
  325. $config{$k} = $v;
  326. } elsif ($_ =~ m/^\s*(\S+)/) {
  327. # We can't reasonably warn on override of toggles (e.g. AlwaysShared)
  328. # because it would get crazy to do so. We'd have to check if the
  329. # current config file being loaded defined the logical opposite setting
  330. # (NeverShared vs. AlwaysShared, etc etc).
  331. $toggle = lc($1); # must normalize key case
  332. $config{$toggle} = $k;
  333. }
  334. }
  335. close(IN);
  336. }
  337. }
  338. }
  339. #
  340. # GetDisplayNumber gets the lowest available display number. A display number
  341. # n is taken if something is listening on the VNC server port (5900+n) or the
  342. # X server port (6000+n).
  343. #
  344. sub GetDisplayNumber
  345. {
  346. foreach $n (1..99) {
  347. if (&CheckDisplayNumber($n)) {
  348. return $n+0; # Bruce Mah's workaround for bug in perl 5.005_02
  349. }
  350. }
  351. die "$prog: no free display number on $host.\n";
  352. }
  353. #
  354. # CheckDisplayNumber checks if the given display number is available. A
  355. # display number n is taken if something is listening on the VNC server port
  356. # (5900+n) or the X server port (6000+n).
  357. #
  358. sub CheckDisplayNumber
  359. {
  360. local ($n) = @_;
  361. socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
  362. eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
  363. if (!bind(S, pack('S n x12', $AF_INET, 6000 + $n))) {
  364. close(S);
  365. return 0;
  366. }
  367. close(S);
  368. socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
  369. eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
  370. if (!bind(S, pack('S n x12', $AF_INET, 5900 + $n))) {
  371. close(S);
  372. return 0;
  373. }
  374. close(S);
  375. if (-e "/tmp/.X$n-lock") {
  376. warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n";
  377. warn "Remove this file if there is no X server $host:$n\n";
  378. return 0;
  379. }
  380. if (-e "/tmp/.X11-unix/X$n") {
  381. warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n";
  382. warn "Remove this file if there is no X server $host:$n\n";
  383. return 0;
  384. }
  385. if (-e "/usr/spool/sockets/X11/$n") {
  386. warn("\nWarning: $host:$n is taken because of ".
  387. "/usr/spool/sockets/X11/$n\n");
  388. warn "Remove this file if there is no X server $host:$n\n";
  389. return 0;
  390. }
  391. return 1;
  392. }
  393. #
  394. # quotedString returns a string which yields the original string when parsed
  395. # by a shell.
  396. #
  397. sub quotedString
  398. {
  399. local ($in) = @_;
  400. $in =~ s/\'/\'\"\'\"\'/g;
  401. return "'$in'";
  402. }
  403. #
  404. # removeSlashes turns slashes into underscores for use as a file name.
  405. #
  406. sub removeSlashes
  407. {
  408. local ($in) = @_;
  409. $in =~ s|/|_|g;
  410. return "$in";
  411. }
  412. #
  413. # Usage
  414. #
  415. sub Usage
  416. {
  417. die("\nusage: $prog [:<number>]\n".
  418. " [-fg]\n".
  419. " [-autokill]\n".
  420. " [-noxstartup]\n".
  421. " [-xstartup <file>]\n".
  422. "\n".
  423. " $prog -kill <X-display>\n\n".
  424. " $prog -list\n\n");
  425. }
  426. #
  427. # List
  428. #
  429. sub List
  430. {
  431. opendir(dir, $vncUserDir);
  432. my @filelist = readdir(dir);
  433. closedir(dir);
  434. print "\nTigerVNC server sessions:\n\n";
  435. print "X DISPLAY #\tPROCESS ID\n";
  436. foreach my $file (@filelist) {
  437. if ($file =~ /$host:(\d+)$\.pid/) {
  438. chop($tmp_pid = `cat $vncUserDir/$file`);
  439. if (kill 0, $tmp_pid) {
  440. print ":".$1."\t\t".`cat $vncUserDir/$file`;
  441. } else {
  442. unlink ($vncUserDir . "/" . $file);
  443. }
  444. }
  445. }
  446. exit;
  447. }
  448. #
  449. # Kill
  450. #
  451. sub Kill
  452. {
  453. $opt{'-kill'} =~ s/(:\d+)\.\d+$/$1/; # e.g. turn :1.0 into :1
  454. if ($opt{'-kill'} =~ /^:\d+$/) {
  455. $pidFile = "$vncUserDir/$host$opt{'-kill'}.pid";
  456. } else {
  457. if ($opt{'-kill'} !~ /^$host:/) {
  458. die "\nCan't tell if $opt{'-kill'} is on $host\n".
  459. "Use -kill :<number> instead\n\n";
  460. }
  461. $pidFile = "$vncUserDir/$opt{'-kill'}.pid";
  462. }
  463. if (! -r $pidFile) {
  464. die "\nCan't find file $pidFile\n".
  465. "You'll have to kill the Xvnc process manually\n\n";
  466. }
  467. $SIG{'HUP'} = 'IGNORE';
  468. chop($pid = `cat $pidFile`);
  469. warn "Killing Xvnc process ID $pid\n";
  470. if (kill 0, $pid) {
  471. system("kill $pid");
  472. sleep(1);
  473. if (kill 0, $pid) {
  474. print "Xvnc seems to be deadlocked. Kill the process manually and then re-run\n";
  475. print " ".$0." -kill ".$opt{'-kill'}."\n";
  476. print "to clean up the socket files.\n";
  477. exit
  478. }
  479. } else {
  480. warn "Xvnc process ID $pid already killed\n";
  481. $opt{'-kill'} =~ s/://;
  482. if (-e "/tmp/.X11-unix/X$opt{'-kill'}") {
  483. print "Xvnc did not appear to shut down cleanly.";
  484. print " Removing /tmp/.X11-unix/X$opt{'-kill'}\n";
  485. unlink "/tmp/.X11-unix/X$opt{'-kill'}";
  486. }
  487. if (-e "/tmp/.X$opt{'-kill'}-lock") {
  488. print "Xvnc did not appear to shut down cleanly.";
  489. print " Removing /tmp/.X$opt{'-kill'}-lock\n";
  490. unlink "/tmp/.X$opt{'-kill'}-lock";
  491. }
  492. }
  493. unlink $pidFile;
  494. exit;
  495. }
  496. #
  497. # ParseOptions takes a list of possible options and a boolean indicating
  498. # whether the option has a value following, and sets up an associative array
  499. # %opt of the values of the options given on the command line. It removes all
  500. # the arguments it uses from @ARGV and returns them in @optArgs.
  501. #
  502. sub ParseOptions
  503. {
  504. local (@optval) = @_;
  505. local ($opt, @opts, %valFollows, @newargs);
  506. while (@optval) {
  507. $opt = shift(@optval);
  508. push(@opts,$opt);
  509. $valFollows{$opt} = shift(@optval);
  510. }
  511. @optArgs = ();
  512. %opt = ();
  513. arg: while (defined($arg = shift(@ARGV))) {
  514. foreach $opt (@opts) {
  515. if ($arg eq $opt) {
  516. push(@optArgs, $arg);
  517. if ($valFollows{$opt}) {
  518. if (@ARGV == 0) {
  519. &Usage();
  520. }
  521. $opt{$opt} = shift(@ARGV);
  522. push(@optArgs, $opt{$opt});
  523. } else {
  524. $opt{$opt} = 1;
  525. }
  526. next arg;
  527. }
  528. }
  529. push(@newargs,$arg);
  530. }
  531. @ARGV = @newargs;
  532. }
  533. # Routine to make sure we're operating in a sane environment.
  534. sub SanityCheck
  535. {
  536. local ($cmd);
  537. # Get the program name
  538. ($prog) = ($0 =~ m|([^/]+)$|);
  539. #
  540. # Check we have all the commands we'll need on the path.
  541. #
  542. cmd:
  543. foreach $cmd ("uname","xauth") {
  544. for (split(/:/,$ENV{PATH})) {
  545. if (-x "$_/$cmd") {
  546. next cmd;
  547. }
  548. }
  549. die "$prog: couldn't find \"$cmd\" on your PATH.\n";
  550. }
  551. if($exedir eq "") {
  552. cmd2:
  553. foreach $cmd ("Xvnc","vncpasswd") {
  554. for (split(/:/,$ENV{PATH})) {
  555. if (-x "$_/$cmd") {
  556. next cmd2;
  557. }
  558. }
  559. die "$prog: couldn't find \"$cmd\" on your PATH.\n";
  560. }
  561. }
  562. else {
  563. cmd3:
  564. foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") {
  565. for (split(/:/,$ENV{PATH})) {
  566. if (-x "$cmd") {
  567. next cmd3;
  568. }
  569. }
  570. die "$prog: couldn't find \"$cmd\".\n";
  571. }
  572. }
  573. if (!defined($ENV{HOME})) {
  574. die "$prog: The HOME environment variable is not set.\n";
  575. }
  576. #
  577. # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an
  578. # eval, and if it fails we try 'require "sys/socket.ph"'. If this fails,
  579. # we just guess at the values. If you find perl moaning here, just
  580. # hard-code the values of AF_INET and SOCK_STREAM. You can find these out
  581. # for your platform by looking in /usr/include/sys/socket.h and related
  582. # files.
  583. #
  584. chop($os = `uname`);
  585. chop($osrev = `uname -r`);
  586. eval 'use Socket';
  587. if ($@) {
  588. eval 'require "sys/socket.ph"';
  589. if ($@) {
  590. if (($os eq "SunOS") && ($osrev !~ /^4/)) {
  591. $AF_INET = 2;
  592. $SOCK_STREAM = 2;
  593. } else {
  594. $AF_INET = 2;
  595. $SOCK_STREAM = 1;
  596. }
  597. } else {
  598. $AF_INET = &AF_INET;
  599. $SOCK_STREAM = &SOCK_STREAM;
  600. }
  601. } else {
  602. $AF_INET = &AF_INET;
  603. $SOCK_STREAM = &SOCK_STREAM;
  604. }
  605. }