| @@ -1,895 +1,895 @@ | | | @@ -1,895 +1,895 @@ |
1 | #!/usr/bin/env perl | | 1 | #!/usr/bin/env perl |
2 | # | | 2 | # |
3 | # Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved. | | 3 | # Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved. |
4 | # Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved. | | 4 | # Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved. |
5 | # Copyright (C) 2002-2003 Constantin Kaplinsky. All Rights Reserved. | | 5 | # Copyright (C) 2002-2003 Constantin Kaplinsky. All Rights Reserved. |
6 | # Copyright (C) 2002-2005 RealVNC Ltd. | | 6 | # Copyright (C) 2002-2005 RealVNC Ltd. |
7 | # Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. | | 7 | # Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. |
8 | # | | 8 | # |
9 | # This is free software; you can redistribute it and/or modify | | 9 | # This is free software; you can redistribute it and/or modify |
10 | # it under the terms of the GNU General Public License as published by | | 10 | # it under the terms of the GNU General Public License as published by |
11 | # the Free Software Foundation; either version 2 of the License, or | | 11 | # the Free Software Foundation; either version 2 of the License, or |
12 | # (at your option) any later version. | | 12 | # (at your option) any later version. |
13 | # | | 13 | # |
14 | # This software is distributed in the hope that it will be useful, | | 14 | # This software is distributed in the hope that it will be useful, |
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | | 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | | 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | # GNU General Public License for more details. | | 17 | # GNU General Public License for more details. |
18 | # | | 18 | # |
19 | # You should have received a copy of the GNU General Public License | | 19 | # You should have received a copy of the GNU General Public License |
20 | # along with this software; if not, write to the Free Software | | 20 | # along with this software; if not, write to the Free Software |
21 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | | 21 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
22 | # USA. | | 22 | # USA. |
23 | # | | 23 | # |
24 | | | 24 | |
25 | # | | 25 | # |
26 | # vncserver - wrapper script to start an X VNC server. | | 26 | # vncserver - wrapper script to start an X VNC server. |
27 | # | | 27 | # |
28 | | | 28 | |
29 | # First make sure we're operating in a sane environment. | | 29 | # First make sure we're operating in a sane environment. |
30 | $exedir = ""; | | 30 | $exedir = ""; |
31 | $slashndx = rindex($0, "/"); | | 31 | $slashndx = rindex($0, "/"); |
32 | if($slashndx>=0) { | | 32 | if($slashndx>=0) { |
33 | $exedir = substr($0, 0, $slashndx+1); | | 33 | $exedir = substr($0, 0, $slashndx+1); |
34 | } | | 34 | } |
35 | | | 35 | |
36 | &SanityCheck(); | | 36 | &SanityCheck(); |
37 | | | 37 | |
38 | # | | 38 | # |
39 | # Global variables. You may want to configure some of these for | | 39 | # Global variables. You may want to configure some of these for |
40 | # your site | | 40 | # your site |
41 | # | | 41 | # |
42 | | | 42 | |
43 | $geometry = "1024x768"; | | 43 | $geometry = "1024x768"; |
44 | #$depth = 16; | | 44 | #$depth = 16; |
45 | | | 45 | |
46 | $vncUserDir = "$ENV{HOME}/.vnc"; | | 46 | $vncUserDir = "$ENV{HOME}/.vnc"; |
47 | $vncUserConfig = "$vncUserDir/config"; | | 47 | $vncUserConfig = "$vncUserDir/config"; |
48 | | | 48 | |
49 | $vncSystemConfigDir = "/etc/tigervnc"; | | 49 | $vncSystemConfigDir = "/etc/tigervnc"; |
50 | $vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults"; | | 50 | $vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults"; |
51 | $vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory"; | | 51 | $vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory"; |
52 | | | 52 | |
53 | $skipxstartup = 0; | | 53 | $skipxstartup = 0; |
54 | $xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority"; | | 54 | $xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority"; |
55 | | | 55 | |
56 | $xstartupFile = $vncUserDir . "/xstartup"; | | 56 | $xstartupFile = $vncUserDir . "/xstartup"; |
57 | $defaultXStartup | | 57 | $defaultXStartup |
58 | = ("#!/bin/sh\n\n". | | 58 | = ("#!/bin/sh\n\n". |
59 | "unset SESSION_MANAGER\n". | | 59 | "unset SESSION_MANAGER\n". |
60 | "unset DBUS_SESSION_BUS_ADDRESS\n". | | 60 | "unset DBUS_SESSION_BUS_ADDRESS\n". |
61 | "OS=`uname -s`\n". | | 61 | "OS=`uname -s`\n". |
62 | "if [ \$OS = 'Linux' ]; then\n". | | 62 | "if [ \$OS = 'Linux' ]; then\n". |
63 | " case \"\$WINDOWMANAGER\" in\n". | | 63 | " case \"\$WINDOWMANAGER\" in\n". |
64 | " \*gnome\*)\n". | | 64 | " \*gnome\*)\n". |
65 | " if [ -e /etc/SuSE-release ]; then\n". | | 65 | " if [ -e /etc/SuSE-release ]; then\n". |
66 | " PATH=\$PATH:/opt/gnome/bin\n". | | 66 | " PATH=\$PATH:/opt/gnome/bin\n". |
67 | " export PATH\n". | | 67 | " export PATH\n". |
68 | " fi\n". | | 68 | " fi\n". |
69 | " ;;\n". | | 69 | " ;;\n". |
70 | " esac\n". | | 70 | " esac\n". |
71 | "fi\n". | | 71 | "fi\n". |
72 | "if [ -x /etc/X11/xinit/xinitrc ]; then\n". | | 72 | "if [ -x /etc/X11/xinit/xinitrc ]; then\n". |
73 | " exec /etc/X11/xinit/xinitrc\n". | | 73 | " exec /etc/X11/xinit/xinitrc\n". |
74 | "fi\n". | | 74 | "fi\n". |
75 | "if [ -f /etc/X11/xinit/xinitrc ]; then\n". | | 75 | "if [ -f /etc/X11/xinit/xinitrc ]; then\n". |
76 | " exec sh /etc/X11/xinit/xinitrc\n". | | 76 | " exec sh /etc/X11/xinit/xinitrc\n". |
77 | "fi\n". | | 77 | "fi\n". |
78 | "[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n". | | 78 | "[ -r \$HOME/.Xresources ] && xrdb \$HOME/.Xresources\n". |
79 | "xsetroot -solid grey\n". | | 79 | "xsetroot -solid grey\n". |
80 | "xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n". | | 80 | "xterm -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n". |
81 | "twm &\n"); | | 81 | "twm &\n"); |
82 | | | 82 | |
83 | $defaultConfig | | 83 | $defaultConfig |
84 | = ("## Supported server options to pass to vncserver upon invocation can be listed\n". | | 84 | = ("## Supported server options to pass to vncserver upon invocation can be listed\n". |
85 | "## in this file. See the following manpages for more: vncserver(1) Xvnc(1).\n". | | 85 | "## in this file. See the following manpages for more: vncserver(1) Xvnc(1).\n". |
86 | "## Several common ones are shown below. Uncomment and modify to your liking.\n". | | 86 | "## Several common ones are shown below. Uncomment and modify to your liking.\n". |
87 | "##\n". | | 87 | "##\n". |
88 | "# securitytypes=vncauth,tlsvnc\n". | | 88 | "# securitytypes=vncauth,tlsvnc\n". |
89 | "# desktop=sandbox\n". | | 89 | "# desktop=sandbox\n". |
90 | "# geometry=2000x1200\n". | | 90 | "# geometry=2000x1200\n". |
91 | "# localhost\n". | | 91 | "# localhost\n". |
92 | "# alwaysshared\n"); | | 92 | "# alwaysshared\n"); |
93 | | | 93 | |
94 | chop($host = `uname -n`); | | 94 | chop($host = `uname -n`); |
95 | | | 95 | |
96 | if (-d "/etc/X11/fontpath.d") { | | 96 | if (-d "/etc/X11/fontpath.d") { |
97 | $fontPath = "catalogue:/etc/X11/fontpath.d"; | | 97 | $fontPath = "catalogue:/etc/X11/fontpath.d"; |
98 | } | | 98 | } |
99 | | | 99 | |
100 | @fontpaths = ('@PREFIX@/share/fonts', '@PREFIX@/share/fonts/X11/'); | | 100 | @fontpaths = ('@PREFIX@/share/fonts', '@PREFIX@/share/fonts/X11/'); |
101 | if (! -l "@X11BASE@") {push(@fontpaths, '@X11BASE@/lib/X11/fonts');} | | 101 | if (! -l "@X11BASE@") {push(@fontpaths, '@X11BASE@/lib/X11/fonts');} |
102 | | | 102 | |
103 | @fonttypes = ('misc', | | 103 | @fonttypes = ('misc', |
104 | '75dpi', | | 104 | '75dpi', |
105 | '100dpi', | | 105 | '100dpi', |
106 | 'Speedo', | | 106 | 'Speedo', |
107 | 'Type1'); | | 107 | 'Type1'); |
108 | | | 108 | |
109 | foreach $_fpath (@fontpaths) { | | 109 | foreach $_fpath (@fontpaths) { |
110 | foreach $_ftype (@fonttypes) { | | 110 | foreach $_ftype (@fonttypes) { |
111 | if (-f "$_fpath/$_ftype/fonts.dir") { | | 111 | if (-f "$_fpath/$_ftype/fonts.dir") { |
112 | if (! -l "$_fpath/$_ftype") { | | 112 | if (! -l "$_fpath/$_ftype") { |
113 | $defFontPath .= "$_fpath/$_ftype,"; | | 113 | $defFontPath .= "$_fpath/$_ftype,"; |
114 | } | | 114 | } |
115 | } | | 115 | } |
116 | } | | 116 | } |
117 | } | | 117 | } |
118 | | | 118 | |
119 | if ($defFontPath) { | | 119 | if ($defFontPath) { |
120 | if (substr($defFontPath, -1, 1) == ',') { | | 120 | if (substr($defFontPath, -1, 1) == ',') { |
121 | chop $defFontPath; | | 121 | chop $defFontPath; |
122 | } | | 122 | } |
123 | } | | 123 | } |
124 | | | 124 | |
125 | if ($fontPath eq "") { | | 125 | if ($fontPath eq "") { |
126 | $fontPath = $defFontPath; | | 126 | $fontPath = $defFontPath; |
127 | } | | 127 | } |
128 | | | 128 | |
129 | # Check command line options | | 129 | # Check command line options |
130 | | | 130 | |
131 | &ParseOptions("-geometry",1,"-depth",1,"-pixelformat",1,"-name",1,"-kill",1, | | 131 | &ParseOptions("-geometry",1,"-depth",1,"-pixelformat",1,"-name",1,"-kill",1, |
132 | "-help",0,"-h",0,"--help",0,"-fp",1,"-list",0,"-fg",0,"-autokill",0,"-noxstartup",0,"-xstartup",1); | | 132 | "-help",0,"-h",0,"--help",0,"-fp",1,"-list",0,"-fg",0,"-autokill",0,"-noxstartup",0,"-xstartup",1); |
133 | | | 133 | |
134 | &Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'}); | | 134 | &Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'}); |
135 | | | 135 | |
136 | &Kill() if ($opt{'-kill'}); | | 136 | &Kill() if ($opt{'-kill'}); |
137 | | | 137 | |
138 | &List() if ($opt{'-list'}); | | 138 | &List() if ($opt{'-list'}); |
139 | | | 139 | |
140 | # Uncomment this line if you want default geometry, depth and pixelformat | | 140 | # Uncomment this line if you want default geometry, depth and pixelformat |
141 | # to match the current X display: | | 141 | # to match the current X display: |
142 | # &GetXDisplayDefaults(); | | 142 | # &GetXDisplayDefaults(); |
143 | | | 143 | |
144 | if ($opt{'-geometry'}) { | | 144 | if ($opt{'-geometry'}) { |
145 | $geometry = $opt{'-geometry'}; | | 145 | $geometry = $opt{'-geometry'}; |
146 | } | | 146 | } |
147 | if ($opt{'-depth'}) { | | 147 | if ($opt{'-depth'}) { |
148 | $depth = $opt{'-depth'}; | | 148 | $depth = $opt{'-depth'}; |
149 | $pixelformat = ""; | | 149 | $pixelformat = ""; |
150 | } | | 150 | } |
151 | if ($opt{'-pixelformat'}) { | | 151 | if ($opt{'-pixelformat'}) { |
152 | $pixelformat = $opt{'-pixelformat'}; | | 152 | $pixelformat = $opt{'-pixelformat'}; |
153 | } | | 153 | } |
154 | if ($opt{'-noxstartup'}) { | | 154 | if ($opt{'-noxstartup'}) { |
155 | $skipxstartup = 1; | | 155 | $skipxstartup = 1; |
156 | } | | 156 | } |
157 | if ($opt{'-xstartup'}) { | | 157 | if ($opt{'-xstartup'}) { |
158 | $xstartupFile = $opt{'-xstartup'}; | | 158 | $xstartupFile = $opt{'-xstartup'}; |
159 | } | | 159 | } |
160 | if ($opt{'-fp'}) { | | 160 | if ($opt{'-fp'}) { |
161 | $fontPath = $opt{'-fp'}; | | 161 | $fontPath = $opt{'-fp'}; |
162 | $fpArgSpecified = 1; | | 162 | $fpArgSpecified = 1; |
163 | } | | 163 | } |
164 | | | 164 | |
165 | &CheckGeometryAndDepth(); | | 165 | &CheckGeometryAndDepth(); |
166 | | | 166 | |
167 | # Create the user's vnc directory if necessary. | | 167 | # Create the user's vnc directory if necessary. |
168 | if (!(-e $vncUserDir)) { | | 168 | if (!(-e $vncUserDir)) { |
169 | if (!mkdir($vncUserDir,0755)) { | | 169 | if (!mkdir($vncUserDir,0755)) { |
170 | die "$prog: Could not create $vncUserDir.\n"; | | 170 | die "$prog: Could not create $vncUserDir.\n"; |
171 | } | | 171 | } |
172 | } | | 172 | } |
173 | | | 173 | |
174 | # Find display number. | | 174 | # Find display number. |
175 | if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) { | | 175 | if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) { |
176 | $displayNumber = $1; | | 176 | $displayNumber = $1; |
177 | shift(@ARGV); | | 177 | shift(@ARGV); |
178 | if (!&CheckDisplayNumber($displayNumber)) { | | 178 | if (!&CheckDisplayNumber($displayNumber)) { |
179 | die "A VNC server is already running as :$displayNumber\n"; | | 179 | die "A VNC server is already running as :$displayNumber\n"; |
180 | } | | 180 | } |
181 | } elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) { | | 181 | } elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) { |
182 | &Usage(); | | 182 | &Usage(); |
183 | } else { | | 183 | } else { |
184 | $displayNumber = &GetDisplayNumber(); | | 184 | $displayNumber = &GetDisplayNumber(); |
185 | } | | 185 | } |
186 | | | 186 | |
187 | $vncPort = 5900 + $displayNumber; | | 187 | $vncPort = 5900 + $displayNumber; |
188 | | | 188 | |
189 | if ($opt{'-name'}) { | | 189 | if ($opt{'-name'}) { |
190 | $desktopName = $opt{'-name'}; | | 190 | $desktopName = $opt{'-name'}; |
191 | } else { | | 191 | } else { |
192 | $desktopName = "$host:$displayNumber ($ENV{USER})"; | | 192 | $desktopName = "$host:$displayNumber ($ENV{USER})"; |
193 | } | | 193 | } |
194 | | | 194 | |
195 | my %default_opts; | | 195 | my %default_opts; |
196 | my %config; | | 196 | my %config; |
197 | | | 197 | |
198 | # We set some reasonable defaults. Config file settings | | 198 | # We set some reasonable defaults. Config file settings |
199 | # override these where present. | | 199 | # override these where present. |
200 | $default_opts{desktop} = "edString($desktopName); | | 200 | $default_opts{desktop} = "edString($desktopName); |
201 | $default_opts{auth} = "edString($xauthorityFile); | | 201 | $default_opts{auth} = "edString($xauthorityFile); |
202 | $default_opts{geometry} = $geometry if ($geometry); | | 202 | $default_opts{geometry} = $geometry if ($geometry); |
203 | $default_opts{depth} = $depth if ($depth); | | 203 | $default_opts{depth} = $depth if ($depth); |
204 | $default_opts{pixelformat} = $pixelformat if ($pixelformat); | | 204 | $default_opts{pixelformat} = $pixelformat if ($pixelformat); |
205 | $default_opts{rfbwait} = 30000; | | 205 | #$default_opts{rfbwait} = 30000; |
206 | $default_opts{rfbauth} = "$vncUserDir/passwd"; | | 206 | $default_opts{rfbauth} = "$vncUserDir/passwd"; |
207 | $default_opts{rfbport} = $vncPort; | | 207 | $default_opts{rfbport} = $vncPort; |
208 | $default_opts{fp} = $fontPath if ($fontPath); | | 208 | $default_opts{fp} = $fontPath if ($fontPath); |
209 | $default_opts{pn} = ""; | | 209 | $default_opts{pn} = ""; |
210 | | | 210 | |
211 | # Load user-overrideable system defaults | | 211 | # Load user-overrideable system defaults |
212 | LoadConfig($vncSystemConfigDefaultsFile); | | 212 | LoadConfig($vncSystemConfigDefaultsFile); |
213 | | | 213 | |
214 | # Then the user's settings | | 214 | # Then the user's settings |
215 | LoadConfig($vncUserConfig); | | 215 | LoadConfig($vncUserConfig); |
216 | | | 216 | |
217 | # And then override anything set above if mandatory settings exist. | | 217 | # And then override anything set above if mandatory settings exist. |
218 | # WARNING: "Mandatory" is used loosely here! As the man page says, | | 218 | # WARNING: "Mandatory" is used loosely here! As the man page says, |
219 | # there is nothing stopping someone from EASILY subverting the | | 219 | # there is nothing stopping someone from EASILY subverting the |
220 | # settings in $vncSystemConfigMandatoryFile by simply passing | | 220 | # settings in $vncSystemConfigMandatoryFile by simply passing |
221 | # CLI args to vncserver, which trump config files! To properly | | 221 | # CLI args to vncserver, which trump config files! To properly |
222 | # hard force policy in a non-subvertible way would require major | | 222 | # hard force policy in a non-subvertible way would require major |
223 | # development work that touches Xvnc itself. | | 223 | # development work that touches Xvnc itself. |
224 | LoadConfig($vncSystemConfigMandatoryFile, 1); | | 224 | LoadConfig($vncSystemConfigMandatoryFile, 1); |
225 | | | 225 | |
226 | # | | 226 | # |
227 | # Check whether VNC authentication is enabled, and if so, prompt the user to | | 227 | # Check whether VNC authentication is enabled, and if so, prompt the user to |
228 | # create a VNC password if they don't already have one. | | 228 | # create a VNC password if they don't already have one. |
229 | # | | 229 | # |
230 | | | 230 | |
231 | $securityTypeArgSpecified = 0; | | 231 | $securityTypeArgSpecified = 0; |
232 | $vncAuthEnabled = 0; | | 232 | $vncAuthEnabled = 0; |
233 | $passwordArgSpecified = 0; | | 233 | $passwordArgSpecified = 0; |
234 | @vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc"); | | 234 | @vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc"); |
235 | | | 235 | |
236 | # ...first we check our configuration files' settings | | 236 | # ...first we check our configuration files' settings |
237 | if ($config{'securitytypes'}) { | | 237 | if ($config{'securitytypes'}) { |
238 | $securityTypeArgSpecified = 1; | | 238 | $securityTypeArgSpecified = 1; |
239 | foreach $arg2 (split(',', $config{'securitytypes'})) { | | 239 | foreach $arg2 (split(',', $config{'securitytypes'})) { |
240 | if (grep {$_ eq lc($arg2)} @vncAuthStrings) { | | 240 | if (grep {$_ eq lc($arg2)} @vncAuthStrings) { |
241 | $vncAuthEnabled = 1; | | 241 | $vncAuthEnabled = 1; |
242 | } | | 242 | } |
243 | } | | 243 | } |
244 | } | | 244 | } |
245 | | | 245 | |
246 | # ...and finally we check CLI args, which in the case of the topic at | | 246 | # ...and finally we check CLI args, which in the case of the topic at |
247 | # hand (VNC auth or not), override anything found in configuration files | | 247 | # hand (VNC auth or not), override anything found in configuration files |
248 | # (even so-called "mandatory" settings). | | 248 | # (even so-called "mandatory" settings). |
249 | for ($i = 0; $i < @ARGV; ++$i) { | | 249 | for ($i = 0; $i < @ARGV; ++$i) { |
250 | # -SecurityTypes can be followed by a space or "=" | | 250 | # -SecurityTypes can be followed by a space or "=" |
251 | my @splitargs = split('=', $ARGV[$i]); | | 251 | my @splitargs = split('=', $ARGV[$i]); |
252 | if (@splitargs <= 1 && $i < @ARGV - 1) { | | 252 | if (@splitargs <= 1 && $i < @ARGV - 1) { |
253 | push(@splitargs, $ARGV[$i + 1]); | | 253 | push(@splitargs, $ARGV[$i + 1]); |
254 | } | | 254 | } |
255 | if (lc(@splitargs[0]) eq "-securitytypes") { | | 255 | if (lc(@splitargs[0]) eq "-securitytypes") { |
256 | if (@splitargs > 1) { | | 256 | if (@splitargs > 1) { |
257 | $securityTypeArgSpecified = 1; | | 257 | $securityTypeArgSpecified = 1; |
258 | } | | 258 | } |
259 | foreach $arg2 (split(',', @splitargs[1])) { | | 259 | foreach $arg2 (split(',', @splitargs[1])) { |
260 | if (grep {$_ eq lc($arg2)} @vncAuthStrings) { | | 260 | if (grep {$_ eq lc($arg2)} @vncAuthStrings) { |
261 | $vncAuthEnabled = 1; | | 261 | $vncAuthEnabled = 1; |
262 | } | | 262 | } |
263 | } | | 263 | } |
264 | } | | 264 | } |
265 | if ((lc(@splitargs[0]) eq "-password") | | 265 | if ((lc(@splitargs[0]) eq "-password") |
266 | || (lc(@splitargs[0]) eq "-passwordfile" | | 266 | || (lc(@splitargs[0]) eq "-passwordfile" |
267 | || (lc(@splitargs[0]) eq "-rfbauth"))) { | | 267 | || (lc(@splitargs[0]) eq "-rfbauth"))) { |
268 | $passwordArgSpecified = 1; | | 268 | $passwordArgSpecified = 1; |
269 | } | | 269 | } |
270 | } | | 270 | } |
271 | | | 271 | |
272 | if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) { | | 272 | if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) { |
273 | ($z,$z,$mode) = stat("$vncUserDir/passwd"); | | 273 | ($z,$z,$mode) = stat("$vncUserDir/passwd"); |
274 | if (!(-e "$vncUserDir/passwd") || ($mode & 077)) { | | 274 | if (!(-e "$vncUserDir/passwd") || ($mode & 077)) { |
275 | warn "\nYou will require a password to access your desktops.\n\n"; | | 275 | warn "\nYou will require a password to access your desktops.\n\n"; |
276 | system($exedir."vncpasswd -q $vncUserDir/passwd"); | | 276 | system($exedir."vncpasswd -q $vncUserDir/passwd"); |
277 | if (($? >> 8) != 0) { | | 277 | if (($? >> 8) != 0) { |
278 | exit 1; | | 278 | exit 1; |
279 | } | | 279 | } |
280 | } | | 280 | } |
281 | } | | 281 | } |
282 | | | 282 | |
283 | $desktopLog = "$vncUserDir/$host:$displayNumber.log"; | | 283 | $desktopLog = "$vncUserDir/$host:$displayNumber.log"; |
284 | unlink($desktopLog); | | 284 | unlink($desktopLog); |
285 | | | 285 | |
286 | # Make an X server cookie and set up the Xauthority file | | 286 | # Make an X server cookie and set up the Xauthority file |
287 | # mcookie is a part of util-linux, usually only GNU/Linux systems have it. | | 287 | # mcookie is a part of util-linux, usually only GNU/Linux systems have it. |
288 | $cookie = `mcookie`; | | 288 | $cookie = `mcookie`; |
289 | # Fallback for non GNU/Linux OS - use /dev/urandom on systems that have it, | | 289 | # Fallback for non GNU/Linux OS - use /dev/urandom on systems that have it, |
290 | # otherwise use perl's random number generator, seeded with the sum | | 290 | # otherwise use perl's random number generator, seeded with the sum |
291 | # of the current time, our PID and part of the encrypted form of the password. | | 291 | # of the current time, our PID and part of the encrypted form of the password. |
292 | if ($cookie eq "" && open(URANDOM, '<', '/dev/urandom')) { | | 292 | if ($cookie eq "" && open(URANDOM, '<', '/dev/urandom')) { |
293 | my $randata; | | 293 | my $randata; |
294 | if (sysread(URANDOM, $randata, 16) == 16) { | | 294 | if (sysread(URANDOM, $randata, 16) == 16) { |
295 | $cookie = unpack 'h*', $randata; | | 295 | $cookie = unpack 'h*', $randata; |
296 | } | | 296 | } |
297 | close(URANDOM); | | 297 | close(URANDOM); |
298 | } | | 298 | } |
299 | if ($cookie eq "") { | | 299 | if ($cookie eq "") { |
300 | srand(time+$$+unpack("L",`cat $vncUserDir/passwd`)); | | 300 | srand(time+$$+unpack("L",`cat $vncUserDir/passwd`)); |
301 | for (1..16) { | | 301 | for (1..16) { |
302 | $cookie .= sprintf("%02x", int(rand(256)) % 256); | | 302 | $cookie .= sprintf("%02x", int(rand(256)) % 256); |
303 | } | | 303 | } |
304 | } | | 304 | } |
305 | | | 305 | |
306 | open(XAUTH, "|xauth -f $xauthorityFile source -"); | | 306 | open(XAUTH, "|xauth -f $xauthorityFile source -"); |
307 | print XAUTH "add $host:$displayNumber . $cookie\n"; | | 307 | print XAUTH "add $host:$displayNumber . $cookie\n"; |
308 | print XAUTH "add $host/unix:$displayNumber . $cookie\n"; | | 308 | print XAUTH "add $host/unix:$displayNumber . $cookie\n"; |
309 | close(XAUTH); | | 309 | close(XAUTH); |
310 | | | 310 | |
311 | # Now start the X VNC Server | | 311 | # Now start the X VNC Server |
312 | | | 312 | |
313 | # We build up our Xvnc command with options | | 313 | # We build up our Xvnc command with options |
314 | $cmd = $exedir."Xvnc :$displayNumber"; | | 314 | $cmd = $exedir."Xvnc :$displayNumber"; |
315 | | | 315 | |
316 | foreach my $k (sort keys %config) { | | 316 | foreach my $k (sort keys %config) { |
317 | $cmd .= " -$k $config{$k}"; | | 317 | $cmd .= " -$k $config{$k}"; |
318 | delete $default_opts{$k}; # file options take precedence | | 318 | delete $default_opts{$k}; # file options take precedence |
319 | } | | 319 | } |
320 | | | 320 | |
321 | foreach my $k (sort keys %default_opts) { | | 321 | foreach my $k (sort keys %default_opts) { |
322 | $cmd .= " -$k $default_opts{$k}"; | | 322 | $cmd .= " -$k $default_opts{$k}"; |
323 | } | | 323 | } |
324 | | | 324 | |
325 | # Add color database stuff here, e.g.: | | 325 | # Add color database stuff here, e.g.: |
326 | # $cmd .= " -co /usr/lib/X11/rgb"; | | 326 | # $cmd .= " -co /usr/lib/X11/rgb"; |
327 | | | 327 | |
328 | foreach $arg (@ARGV) { | | 328 | foreach $arg (@ARGV) { |
329 | $cmd .= " " . "edString($arg); | | 329 | $cmd .= " " . "edString($arg); |
330 | } | | 330 | } |
331 | $cmd .= " >> " . "edString($desktopLog) . " 2>&1"; | | 331 | $cmd .= " >> " . "edString($desktopLog) . " 2>&1"; |
332 | | | 332 | |
333 | # Run $cmd and record the process ID. | | 333 | # Run $cmd and record the process ID. |
334 | $pidFile = "$vncUserDir/$host:$displayNumber.pid"; | | 334 | $pidFile = "$vncUserDir/$host:$displayNumber.pid"; |
335 | system("$cmd & echo \$! >$pidFile"); | | 335 | system("$cmd & echo \$! >$pidFile"); |
336 | | | 336 | |
337 | # Give Xvnc a chance to start up | | 337 | # Give Xvnc a chance to start up |
338 | | | 338 | |
339 | sleep(3); | | 339 | sleep(3); |
340 | if ($fontPath ne $defFontPath) { | | 340 | if ($fontPath ne $defFontPath) { |
341 | unless (kill 0, `cat $pidFile`) { | | 341 | unless (kill 0, `cat $pidFile`) { |
342 | if ($fpArgSpecified) { | | 342 | if ($fpArgSpecified) { |
343 | warn "\nWARNING: The first attempt to start Xvnc failed, probably because the font\n"; | | 343 | warn "\nWARNING: The first attempt to start Xvnc failed, probably because the font\n"; |
344 | warn "path you specified using the -fp argument is incorrect. Attempting to\n"; | | 344 | warn "path you specified using the -fp argument is incorrect. Attempting to\n"; |
345 | warn "determine an appropriate font path for this system and restart Xvnc using\n"; | | 345 | warn "determine an appropriate font path for this system and restart Xvnc using\n"; |
346 | warn "that font path ...\n"; | | 346 | warn "that font path ...\n"; |
347 | } else { | | 347 | } else { |
348 | warn "\nWARNING: The first attempt to start Xvnc failed, possibly because the font\n"; | | 348 | warn "\nWARNING: The first attempt to start Xvnc failed, possibly because the font\n"; |
349 | warn "catalog is not properly configured. Attempting to determine an appropriate\n"; | | 349 | warn "catalog is not properly configured. Attempting to determine an appropriate\n"; |
350 | warn "font path for this system and restart Xvnc using that font path ...\n"; | | 350 | warn "font path for this system and restart Xvnc using that font path ...\n"; |
351 | } | | 351 | } |
352 | $cmd =~ s@-fp [^ ]+@@; | | 352 | $cmd =~ s@-fp [^ ]+@@; |
353 | $cmd .= " -fp $defFontPath" if ($defFontPath); | | 353 | $cmd .= " -fp $defFontPath" if ($defFontPath); |
354 | system("$cmd & echo \$! >$pidFile"); | | 354 | system("$cmd & echo \$! >$pidFile"); |
355 | sleep(3); | | 355 | sleep(3); |
356 | } | | 356 | } |
357 | } | | 357 | } |
358 | unless (kill 0, `cat $pidFile`) { | | 358 | unless (kill 0, `cat $pidFile`) { |
359 | warn "Could not start Xvnc.\n\n"; | | 359 | warn "Could not start Xvnc.\n\n"; |
360 | unlink $pidFile; | | 360 | unlink $pidFile; |
361 | open(LOG, "<$desktopLog"); | | 361 | open(LOG, "<$desktopLog"); |
362 | while (<LOG>) { print; } | | 362 | while (<LOG>) { print; } |
363 | close(LOG); | | 363 | close(LOG); |
364 | die "\n"; | | 364 | die "\n"; |
365 | } | | 365 | } |
366 | | | 366 | |
367 | warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n"; | | 367 | warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n"; |
368 | | | 368 | |
369 | # Create the user's xstartup script if necessary. | | 369 | # Create the user's xstartup script if necessary. |
370 | if (! $skipxstartup) { | | 370 | if (! $skipxstartup) { |
371 | if (!(-e "$xstartupFile")) { | | 371 | if (!(-e "$xstartupFile")) { |
372 | warn "Creating default startup script $xstartupFile\n"; | | 372 | warn "Creating default startup script $xstartupFile\n"; |
373 | open(XSTARTUP, ">$xstartupFile"); | | 373 | open(XSTARTUP, ">$xstartupFile"); |
374 | print XSTARTUP $defaultXStartup; | | 374 | print XSTARTUP $defaultXStartup; |
375 | close(XSTARTUP); | | 375 | close(XSTARTUP); |
376 | chmod 0755, "$xstartupFile"; | | 376 | chmod 0755, "$xstartupFile"; |
377 | } | | 377 | } |
378 | } | | 378 | } |
379 | | | 379 | |
380 | # Create the user's config file if necessary. | | 380 | # Create the user's config file if necessary. |
381 | if (!(-e "$vncUserDir/config")) { | | 381 | if (!(-e "$vncUserDir/config")) { |
382 | warn "Creating default config $vncUserDir/config\n"; | | 382 | warn "Creating default config $vncUserDir/config\n"; |
383 | open(VNCUSERCONFIG, ">$vncUserDir/config"); | | 383 | open(VNCUSERCONFIG, ">$vncUserDir/config"); |
384 | print VNCUSERCONFIG $defaultConfig; | | 384 | print VNCUSERCONFIG $defaultConfig; |
385 | close(VNCUSERCONFIG); | | 385 | close(VNCUSERCONFIG); |
386 | chmod 0644, "$vncUserDir/config"; | | 386 | chmod 0644, "$vncUserDir/config"; |
387 | } | | 387 | } |
388 | | | 388 | |
389 | # Run the X startup script. | | 389 | # Run the X startup script. |
390 | if (! $skipxstartup) { | | 390 | if (! $skipxstartup) { |
391 | warn "Starting applications specified in $xstartupFile\n"; | | 391 | warn "Starting applications specified in $xstartupFile\n"; |
392 | } | | 392 | } |
393 | warn "Log file is $desktopLog\n\n"; | | 393 | warn "Log file is $desktopLog\n\n"; |
394 | | | 394 | |
395 | # If the unix domain socket exists then use that (DISPLAY=:n) otherwise use | | 395 | # If the unix domain socket exists then use that (DISPLAY=:n) otherwise use |
396 | # TCP (DISPLAY=host:n) | | 396 | # TCP (DISPLAY=host:n) |
397 | | | 397 | |
398 | if (-e "/tmp/.X11-unix/X$displayNumber" || | | 398 | if (-e "/tmp/.X11-unix/X$displayNumber" || |
399 | -e "/usr/spool/sockets/X11/$displayNumber") | | 399 | -e "/usr/spool/sockets/X11/$displayNumber") |
400 | { | | 400 | { |
401 | $ENV{DISPLAY}= ":$displayNumber"; | | 401 | $ENV{DISPLAY}= ":$displayNumber"; |
402 | } else { | | 402 | } else { |
403 | $ENV{DISPLAY}= "$host:$displayNumber"; | | 403 | $ENV{DISPLAY}= "$host:$displayNumber"; |
404 | } | | 404 | } |
405 | $ENV{VNCDESKTOP}= $desktopName; | | 405 | $ENV{VNCDESKTOP}= $desktopName; |
406 | | | 406 | |
407 | if ($opt{'-fg'}) { | | 407 | if ($opt{'-fg'}) { |
408 | if (! $skipxstartup) { | | 408 | if (! $skipxstartup) { |
409 | system("$xstartupFile >> " . "edString($desktopLog) . " 2>&1"); | | 409 | system("$xstartupFile >> " . "edString($desktopLog) . " 2>&1"); |
410 | } | | 410 | } |
411 | if (kill 0, `cat $pidFile`) { | | 411 | if (kill 0, `cat $pidFile`) { |
412 | $opt{'-kill'} = ':'.$displayNumber; | | 412 | $opt{'-kill'} = ':'.$displayNumber; |
413 | &Kill(); | | 413 | &Kill(); |
414 | } | | 414 | } |
415 | } else { | | 415 | } else { |
416 | if ($opt{'-autokill'}) { | | 416 | if ($opt{'-autokill'}) { |
417 | if (! $skipxstartup) { | | 417 | if (! $skipxstartup) { |
418 | system("($xstartupFile; $0 -kill :$displayNumber) >> " | | 418 | system("($xstartupFile; $0 -kill :$displayNumber) >> " |
419 | . "edString($desktopLog) . " 2>&1 &"); | | 419 | . "edString($desktopLog) . " 2>&1 &"); |
420 | } | | 420 | } |
421 | } else { | | 421 | } else { |
422 | if (! $skipxstartup) { | | 422 | if (! $skipxstartup) { |
423 | system("$xstartupFile >> " . "edString($desktopLog) | | 423 | system("$xstartupFile >> " . "edString($desktopLog) |
424 | . " 2>&1 &"); | | 424 | . " 2>&1 &"); |
425 | } | | 425 | } |
426 | } | | 426 | } |
427 | } | | 427 | } |
428 | | | 428 | |
429 | exit; | | 429 | exit; |
430 | | | 430 | |
431 | ############################################################################### | | 431 | ############################################################################### |
432 | # Functions | | 432 | # Functions |
433 | ############################################################################### | | 433 | ############################################################################### |
434 | | | 434 | |
435 | # | | 435 | # |
436 | # Populate the global %config hash with settings from a specified | | 436 | # Populate the global %config hash with settings from a specified |
437 | # vncserver configuration file if it exists | | 437 | # vncserver configuration file if it exists |
438 | # | | 438 | # |
439 | # Args: 1. file path | | 439 | # Args: 1. file path |
440 | # 2. optional boolean flag to enable warning when a previously | | 440 | # 2. optional boolean flag to enable warning when a previously |
441 | # set configuration setting is being overridden | | 441 | # set configuration setting is being overridden |
442 | # | | 442 | # |
443 | sub LoadConfig { | | 443 | sub LoadConfig { |
444 | local ($configFile, $warnoverride) = @_; | | 444 | local ($configFile, $warnoverride) = @_; |
445 | local ($toggle) = undef; | | 445 | local ($toggle) = undef; |
446 | | | 446 | |
447 | if (stat($configFile)) { | | 447 | if (stat($configFile)) { |
448 | if (open(IN, $configFile)) { | | 448 | if (open(IN, $configFile)) { |
449 | while (<IN>) { | | 449 | while (<IN>) { |
450 | next if /^#/; | | 450 | next if /^#/; |
451 | if (my ($k, $v) = /^\s*(\w+)\s*=\s*(.+)$/) { | | 451 | if (my ($k, $v) = /^\s*(\w+)\s*=\s*(.+)$/) { |
452 | $k = lc($k); # must normalize key case | | 452 | $k = lc($k); # must normalize key case |
453 | if ($warnoverride && $config{$k}) { | | 453 | if ($warnoverride && $config{$k}) { |
454 | print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n"); | | 454 | print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n"); |
455 | } | | 455 | } |
456 | $config{$k} = $v; | | 456 | $config{$k} = $v; |
457 | } elsif ($_ =~ m/^\s*(\S+)/) { | | 457 | } elsif ($_ =~ m/^\s*(\S+)/) { |
458 | # We can't reasonably warn on override of toggles (e.g. AlwaysShared) | | 458 | # We can't reasonably warn on override of toggles (e.g. AlwaysShared) |
459 | # because it would get crazy to do so. We'd have to check if the | | 459 | # because it would get crazy to do so. We'd have to check if the |
460 | # current config file being loaded defined the logical opposite setting | | 460 | # current config file being loaded defined the logical opposite setting |
461 | # (NeverShared vs. AlwaysShared, etc etc). | | 461 | # (NeverShared vs. AlwaysShared, etc etc). |
462 | $toggle = lc($1); # must normalize key case | | 462 | $toggle = lc($1); # must normalize key case |
463 | $config{$toggle} = $k; | | 463 | $config{$toggle} = $k; |
464 | } | | 464 | } |
465 | } | | 465 | } |
466 | close(IN); | | 466 | close(IN); |
467 | } | | 467 | } |
468 | } | | 468 | } |
469 | } | | 469 | } |
470 | | | 470 | |
471 | # | | 471 | # |
472 | # CheckGeometryAndDepth simply makes sure that the geometry and depth values | | 472 | # CheckGeometryAndDepth simply makes sure that the geometry and depth values |
473 | # are sensible. | | 473 | # are sensible. |
474 | # | | 474 | # |
475 | | | 475 | |
476 | sub CheckGeometryAndDepth | | 476 | sub CheckGeometryAndDepth |
477 | { | | 477 | { |
478 | if ($geometry =~ /^(\d+)x(\d+)$/) { | | 478 | if ($geometry =~ /^(\d+)x(\d+)$/) { |
479 | $width = $1; $height = $2; | | 479 | $width = $1; $height = $2; |
480 | | | 480 | |
481 | if (($width<1) || ($height<1)) { | | 481 | if (($width<1) || ($height<1)) { |
482 | die "$prog: geometry $geometry is invalid\n"; | | 482 | die "$prog: geometry $geometry is invalid\n"; |
483 | } | | 483 | } |
484 | | | 484 | |
485 | $geometry = "${width}x$height"; | | 485 | $geometry = "${width}x$height"; |
486 | } else { | | 486 | } else { |
487 | die "$prog: geometry $geometry is invalid\n"; | | 487 | die "$prog: geometry $geometry is invalid\n"; |
488 | } | | 488 | } |
489 | | | 489 | |
490 | if ($depth && (($depth < 8) || ($depth > 32))) { | | 490 | if ($depth && (($depth < 8) || ($depth > 32))) { |
491 | die "Depth must be between 8 and 32\n"; | | 491 | die "Depth must be between 8 and 32\n"; |
492 | } | | 492 | } |
493 | } | | 493 | } |
494 | | | 494 | |
495 | | | 495 | |
496 | # | | 496 | # |
497 | # GetDisplayNumber gets the lowest available display number. A display number | | 497 | # GetDisplayNumber gets the lowest available display number. A display number |
498 | # n is taken if something is listening on the VNC server port (5900+n) or the | | 498 | # n is taken if something is listening on the VNC server port (5900+n) or the |
499 | # X server port (6000+n). | | 499 | # X server port (6000+n). |
500 | # | | 500 | # |
501 | | | 501 | |
502 | sub GetDisplayNumber | | 502 | sub GetDisplayNumber |
503 | { | | 503 | { |
504 | foreach $n (1..99) { | | 504 | foreach $n (1..99) { |
505 | if (&CheckDisplayNumber($n)) { | | 505 | if (&CheckDisplayNumber($n)) { |
506 | return $n+0; # Bruce Mah's workaround for bug in perl 5.005_02 | | 506 | return $n+0; # Bruce Mah's workaround for bug in perl 5.005_02 |
507 | } | | 507 | } |
508 | } | | 508 | } |
509 | | | 509 | |
510 | die "$prog: no free display number on $host.\n"; | | 510 | die "$prog: no free display number on $host.\n"; |
511 | } | | 511 | } |
512 | | | 512 | |
513 | | | 513 | |
514 | # | | 514 | # |
515 | # CheckDisplayNumber checks if the given display number is available. A | | 515 | # CheckDisplayNumber checks if the given display number is available. A |
516 | # display number n is taken if something is listening on the VNC server port | | 516 | # display number n is taken if something is listening on the VNC server port |
517 | # (5900+n) or the X server port (6000+n). | | 517 | # (5900+n) or the X server port (6000+n). |
518 | # | | 518 | # |
519 | | | 519 | |
520 | sub CheckDisplayNumber | | 520 | sub CheckDisplayNumber |
521 | { | | 521 | { |
522 | local ($n) = @_; | | 522 | local ($n) = @_; |
523 | | | 523 | |
524 | socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; | | 524 | socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; |
525 | eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; | | 525 | eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; |
526 | if (!bind(S, sockaddr_in(6000 + $n, &INADDR_ANY))) { | | 526 | if (!bind(S, sockaddr_in(6000 + $n, &INADDR_ANY))) { |
527 | close(S); | | 527 | close(S); |
528 | return 0; | | 528 | return 0; |
529 | } | | 529 | } |
530 | close(S); | | 530 | close(S); |
531 | | | 531 | |
532 | socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; | | 532 | socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; |
533 | eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; | | 533 | eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; |
534 | if (!bind(S, sockaddr_in(5900 + $n, &INADDR_ANY))) { | | 534 | if (!bind(S, sockaddr_in(5900 + $n, &INADDR_ANY))) { |
535 | close(S); | | 535 | close(S); |
536 | return 0; | | 536 | return 0; |
537 | } | | 537 | } |
538 | close(S); | | 538 | close(S); |
539 | | | 539 | |
540 | if (-e "/tmp/.X$n-lock") { | | 540 | if (-e "/tmp/.X$n-lock") { |
541 | warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n"; | | 541 | warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n"; |
542 | warn "Remove this file if there is no X server $host:$n\n"; | | 542 | warn "Remove this file if there is no X server $host:$n\n"; |
543 | return 0; | | 543 | return 0; |
544 | } | | 544 | } |
545 | | | 545 | |
546 | if (-e "/tmp/.X11-unix/X$n") { | | 546 | if (-e "/tmp/.X11-unix/X$n") { |
547 | warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n"; | | 547 | warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n"; |
548 | warn "Remove this file if there is no X server $host:$n\n"; | | 548 | warn "Remove this file if there is no X server $host:$n\n"; |
549 | return 0; | | 549 | return 0; |
550 | } | | 550 | } |
551 | | | 551 | |
552 | if (-e "/usr/spool/sockets/X11/$n") { | | 552 | if (-e "/usr/spool/sockets/X11/$n") { |
553 | warn("\nWarning: $host:$n is taken because of ". | | 553 | warn("\nWarning: $host:$n is taken because of ". |
554 | "/usr/spool/sockets/X11/$n\n"); | | 554 | "/usr/spool/sockets/X11/$n\n"); |
555 | warn "Remove this file if there is no X server $host:$n\n"; | | 555 | warn "Remove this file if there is no X server $host:$n\n"; |
556 | return 0; | | 556 | return 0; |
557 | } | | 557 | } |
558 | | | 558 | |
559 | return 1; | | 559 | return 1; |
560 | } | | 560 | } |
561 | | | 561 | |
562 | | | 562 | |
563 | # | | 563 | # |
564 | # GetXDisplayDefaults uses xdpyinfo to find out the geometry, depth and pixel | | 564 | # GetXDisplayDefaults uses xdpyinfo to find out the geometry, depth and pixel |
565 | # format of the current X display being used. If successful, it sets the | | 565 | # format of the current X display being used. If successful, it sets the |
566 | # options as appropriate so that the X VNC server will use the same settings | | 566 | # options as appropriate so that the X VNC server will use the same settings |
567 | # (minus an allowance for window manager decorations on the geometry). Using | | 567 | # (minus an allowance for window manager decorations on the geometry). Using |
568 | # the same depth and pixel format means that the VNC server won't have to | | 568 | # the same depth and pixel format means that the VNC server won't have to |
569 | # translate pixels when the desktop is being viewed on this X display (for | | 569 | # translate pixels when the desktop is being viewed on this X display (for |
570 | # TrueColor displays anyway). | | 570 | # TrueColor displays anyway). |
571 | # | | 571 | # |
572 | | | 572 | |
573 | sub GetXDisplayDefaults | | 573 | sub GetXDisplayDefaults |
574 | { | | 574 | { |
575 | local (@lines, @matchlines, $width, $height, $defaultVisualId, $i, | | 575 | local (@lines, @matchlines, $width, $height, $defaultVisualId, $i, |
576 | $red, $green, $blue); | | 576 | $red, $green, $blue); |
577 | | | 577 | |
578 | $wmDecorationWidth = 4; # a guess at typical size for window manager | | 578 | $wmDecorationWidth = 4; # a guess at typical size for window manager |
579 | $wmDecorationHeight = 24; # decoration size | | 579 | $wmDecorationHeight = 24; # decoration size |
580 | | | 580 | |
581 | return if (!defined($ENV{DISPLAY})); | | 581 | return if (!defined($ENV{DISPLAY})); |
582 | | | 582 | |
583 | @lines = `xdpyinfo 2>/dev/null`; | | 583 | @lines = `xdpyinfo 2>/dev/null`; |
584 | | | 584 | |
585 | return if ($? != 0); | | 585 | return if ($? != 0); |
586 | | | 586 | |
587 | @matchlines = grep(/dimensions/, @lines); | | 587 | @matchlines = grep(/dimensions/, @lines); |
588 | if (@matchlines) { | | 588 | if (@matchlines) { |
589 | ($width, $height) = ($matchlines[0] =~ /(\d+)x(\d+) pixels/); | | 589 | ($width, $height) = ($matchlines[0] =~ /(\d+)x(\d+) pixels/); |
590 | | | 590 | |
591 | $width -= $wmDecorationWidth; | | 591 | $width -= $wmDecorationWidth; |
592 | $height -= $wmDecorationHeight; | | 592 | $height -= $wmDecorationHeight; |
593 | | | 593 | |
594 | $geometry = "${width}x$height"; | | 594 | $geometry = "${width}x$height"; |
595 | } | | 595 | } |
596 | | | 596 | |
597 | @matchlines = grep(/default visual id/, @lines); | | 597 | @matchlines = grep(/default visual id/, @lines); |
598 | if (@matchlines) { | | 598 | if (@matchlines) { |
599 | ($defaultVisualId) = ($matchlines[0] =~ /id:\s+(\S+)/); | | 599 | ($defaultVisualId) = ($matchlines[0] =~ /id:\s+(\S+)/); |
600 | | | 600 | |
601 | for ($i = 0; $i < @lines; $i++) { | | 601 | for ($i = 0; $i < @lines; $i++) { |
602 | if ($lines[$i] =~ /^\s*visual id:\s+$defaultVisualId$/) { | | 602 | if ($lines[$i] =~ /^\s*visual id:\s+$defaultVisualId$/) { |
603 | if (($lines[$i+1] !~ /TrueColor/) || | | 603 | if (($lines[$i+1] !~ /TrueColor/) || |
604 | ($lines[$i+2] !~ /depth/) || | | 604 | ($lines[$i+2] !~ /depth/) || |
605 | ($lines[$i+4] !~ /red, green, blue masks/)) | | 605 | ($lines[$i+4] !~ /red, green, blue masks/)) |
606 | { | | 606 | { |
607 | return; | | 607 | return; |
608 | } | | 608 | } |
609 | last; | | 609 | last; |
610 | } | | 610 | } |
611 | } | | 611 | } |
612 | | | 612 | |
613 | return if ($i >= @lines); | | 613 | return if ($i >= @lines); |
614 | | | 614 | |
615 | ($depth) = ($lines[$i+2] =~ /depth:\s+(\d+)/); | | 615 | ($depth) = ($lines[$i+2] =~ /depth:\s+(\d+)/); |
616 | ($red,$green,$blue) | | 616 | ($red,$green,$blue) |
617 | = ($lines[$i+4] | | 617 | = ($lines[$i+4] |
618 | =~ /masks:\s+0x([0-9a-f]+), 0x([0-9a-f]+), 0x([0-9a-f]+)/); | | 618 | =~ /masks:\s+0x([0-9a-f]+), 0x([0-9a-f]+), 0x([0-9a-f]+)/); |
619 | | | 619 | |
620 | $red = hex($red); | | 620 | $red = hex($red); |
621 | $green = hex($green); | | 621 | $green = hex($green); |
622 | $blue = hex($blue); | | 622 | $blue = hex($blue); |
623 | | | 623 | |
624 | if ($red > $blue) { | | 624 | if ($red > $blue) { |
625 | $red = int(log($red) / log(2)) - int(log($green) / log(2)); | | 625 | $red = int(log($red) / log(2)) - int(log($green) / log(2)); |
626 | $green = int(log($green) / log(2)) - int(log($blue) / log(2)); | | 626 | $green = int(log($green) / log(2)) - int(log($blue) / log(2)); |
627 | $blue = int(log($blue) / log(2)) + 1; | | 627 | $blue = int(log($blue) / log(2)) + 1; |
628 | $pixelformat = "rgb$red$green$blue"; | | 628 | $pixelformat = "rgb$red$green$blue"; |
629 | } else { | | 629 | } else { |
630 | $blue = int(log($blue) / log(2)) - int(log($green) / log(2)); | | 630 | $blue = int(log($blue) / log(2)) - int(log($green) / log(2)); |
631 | $green = int(log($green) / log(2)) - int(log($red) / log(2)); | | 631 | $green = int(log($green) / log(2)) - int(log($red) / log(2)); |
632 | $red = int(log($red) / log(2)) + 1; | | 632 | $red = int(log($red) / log(2)) + 1; |
633 | $pixelformat = "bgr$blue$green$red"; | | 633 | $pixelformat = "bgr$blue$green$red"; |
634 | } | | 634 | } |
635 | } | | 635 | } |
636 | } | | 636 | } |
637 | | | 637 | |
638 | | | 638 | |
639 | # | | 639 | # |
640 | # quotedString returns a string which yields the original string when parsed | | 640 | # quotedString returns a string which yields the original string when parsed |
641 | # by a shell. | | 641 | # by a shell. |
642 | # | | 642 | # |
643 | | | 643 | |
644 | sub quotedString | | 644 | sub quotedString |
645 | { | | 645 | { |
646 | local ($in) = @_; | | 646 | local ($in) = @_; |
647 | | | 647 | |
648 | $in =~ s/\'/\'\"\'\"\'/g; | | 648 | $in =~ s/\'/\'\"\'\"\'/g; |
649 | | | 649 | |
650 | return "'$in'"; | | 650 | return "'$in'"; |
651 | } | | 651 | } |
652 | | | 652 | |
653 | | | 653 | |
654 | # | | 654 | # |
655 | # removeSlashes turns slashes into underscores for use as a file name. | | 655 | # removeSlashes turns slashes into underscores for use as a file name. |
656 | # | | 656 | # |
657 | | | 657 | |
658 | sub removeSlashes | | 658 | sub removeSlashes |
659 | { | | 659 | { |
660 | local ($in) = @_; | | 660 | local ($in) = @_; |
661 | | | 661 | |
662 | $in =~ s|/|_|g; | | 662 | $in =~ s|/|_|g; |
663 | | | 663 | |
664 | return "$in"; | | 664 | return "$in"; |
665 | } | | 665 | } |
666 | | | 666 | |
667 | | | 667 | |
668 | # | | 668 | # |
669 | # Usage | | 669 | # Usage |
670 | # | | 670 | # |
671 | | | 671 | |
672 | sub Usage | | 672 | sub Usage |
673 | { | | 673 | { |
674 | die("\nusage: $prog [:<number>] [-name <desktop-name>] [-depth <depth>]\n". | | 674 | die("\nusage: $prog [:<number>] [-name <desktop-name>] [-depth <depth>]\n". |
675 | " [-geometry <width>x<height>]\n". | | 675 | " [-geometry <width>x<height>]\n". |
676 | " [-pixelformat rgbNNN|bgrNNN]\n". | | 676 | " [-pixelformat rgbNNN|bgrNNN]\n". |
677 | " [-fp <font-path>]\n". | | 677 | " [-fp <font-path>]\n". |
678 | " [-fg]\n". | | 678 | " [-fg]\n". |
679 | " [-autokill]\n". | | 679 | " [-autokill]\n". |
680 | " [-noxstartup]\n". | | 680 | " [-noxstartup]\n". |
681 | " [-xstartup <file>]\n". | | 681 | " [-xstartup <file>]\n". |
682 | " <Xvnc-options>...\n\n". | | 682 | " <Xvnc-options>...\n\n". |
683 | " $prog -kill <X-display>\n\n". | | 683 | " $prog -kill <X-display>\n\n". |
684 | " $prog -list\n\n"); | | 684 | " $prog -list\n\n"); |
685 | } | | 685 | } |
686 | | | 686 | |
687 | | | 687 | |
688 | # | | 688 | # |
689 | # List | | 689 | # List |
690 | # | | 690 | # |
691 | | | 691 | |
692 | sub List | | 692 | sub List |
693 | { | | 693 | { |
694 | opendir(dir, $vncUserDir); | | 694 | opendir(dir, $vncUserDir); |
695 | my @filelist = readdir(dir); | | 695 | my @filelist = readdir(dir); |
696 | closedir(dir); | | 696 | closedir(dir); |
697 | print "\nTigerVNC server sessions:\n\n"; | | 697 | print "\nTigerVNC server sessions:\n\n"; |
698 | print "X DISPLAY #\tPROCESS ID\n"; | | 698 | print "X DISPLAY #\tPROCESS ID\n"; |
699 | foreach my $file (@filelist) { | | 699 | foreach my $file (@filelist) { |
700 | if ($file =~ /$host:(\d+)$\.pid/) { | | 700 | if ($file =~ /$host:(\d+)$\.pid/) { |
701 | chop($tmp_pid = `cat $vncUserDir/$file`); | | 701 | chop($tmp_pid = `cat $vncUserDir/$file`); |
702 | if (kill 0, $tmp_pid) { | | 702 | if (kill 0, $tmp_pid) { |
703 | print ":".$1."\t\t".`cat $vncUserDir/$file`; | | 703 | print ":".$1."\t\t".`cat $vncUserDir/$file`; |
704 | } else { | | 704 | } else { |
705 | unlink ($vncUserDir . "/" . $file); | | 705 | unlink ($vncUserDir . "/" . $file); |
706 | } | | 706 | } |
707 | } | | 707 | } |
708 | } | | 708 | } |
709 | exit; | | 709 | exit; |
710 | } | | 710 | } |
711 | | | 711 | |
712 | | | 712 | |
713 | # | | 713 | # |
714 | # Kill | | 714 | # Kill |
715 | # | | 715 | # |
716 | | | 716 | |
717 | sub Kill | | 717 | sub Kill |
718 | { | | 718 | { |
719 | $opt{'-kill'} =~ s/(:\d+)\.\d+$/$1/; # e.g. turn :1.0 into :1 | | 719 | $opt{'-kill'} =~ s/(:\d+)\.\d+$/$1/; # e.g. turn :1.0 into :1 |
720 | | | 720 | |
721 | if ($opt{'-kill'} =~ /^:\d+$/) { | | 721 | if ($opt{'-kill'} =~ /^:\d+$/) { |
722 | $pidFile = "$vncUserDir/$host$opt{'-kill'}.pid"; | | 722 | $pidFile = "$vncUserDir/$host$opt{'-kill'}.pid"; |
723 | } else { | | 723 | } else { |
724 | if ($opt{'-kill'} !~ /^$host:/) { | | 724 | if ($opt{'-kill'} !~ /^$host:/) { |
725 | die "\nCan't tell if $opt{'-kill'} is on $host\n". | | 725 | die "\nCan't tell if $opt{'-kill'} is on $host\n". |
726 | "Use -kill :<number> instead\n\n"; | | 726 | "Use -kill :<number> instead\n\n"; |
727 | } | | 727 | } |
728 | $pidFile = "$vncUserDir/$opt{'-kill'}.pid"; | | 728 | $pidFile = "$vncUserDir/$opt{'-kill'}.pid"; |
729 | } | | 729 | } |
730 | | | 730 | |
731 | if (! -r $pidFile) { | | 731 | if (! -r $pidFile) { |
732 | die "\nCan't find file $pidFile\n". | | 732 | die "\nCan't find file $pidFile\n". |
733 | "You'll have to kill the Xvnc process manually\n\n"; | | 733 | "You'll have to kill the Xvnc process manually\n\n"; |
734 | } | | 734 | } |
735 | | | 735 | |
736 | $SIG{'HUP'} = 'IGNORE'; | | 736 | $SIG{'HUP'} = 'IGNORE'; |
737 | chop($pid = `cat $pidFile`); | | 737 | chop($pid = `cat $pidFile`); |
738 | warn "Killing Xvnc process ID $pid\n"; | | 738 | warn "Killing Xvnc process ID $pid\n"; |
739 | | | 739 | |
740 | if (kill 0, $pid) { | | 740 | if (kill 0, $pid) { |
741 | system("kill $pid"); | | 741 | system("kill $pid"); |
742 | sleep(1); | | 742 | sleep(1); |
743 | if (kill 0, $pid) { | | 743 | if (kill 0, $pid) { |
744 | print "Xvnc seems to be deadlocked. Kill the process manually and then re-run\n"; | | 744 | print "Xvnc seems to be deadlocked. Kill the process manually and then re-run\n"; |
745 | print " ".$0." -kill ".$opt{'-kill'}."\n"; | | 745 | print " ".$0." -kill ".$opt{'-kill'}."\n"; |
746 | print "to clean up the socket files.\n"; | | 746 | print "to clean up the socket files.\n"; |
747 | exit | | 747 | exit |
748 | } | | 748 | } |
749 | | | 749 | |
750 | } else { | | 750 | } else { |
751 | warn "Xvnc process ID $pid already killed\n"; | | 751 | warn "Xvnc process ID $pid already killed\n"; |
752 | $opt{'-kill'} =~ s/://; | | 752 | $opt{'-kill'} =~ s/://; |
753 | | | 753 | |
754 | if (-e "/tmp/.X11-unix/X$opt{'-kill'}") { | | 754 | if (-e "/tmp/.X11-unix/X$opt{'-kill'}") { |
755 | print "Xvnc did not appear to shut down cleanly."; | | 755 | print "Xvnc did not appear to shut down cleanly."; |
756 | print " Removing /tmp/.X11-unix/X$opt{'-kill'}\n"; | | 756 | print " Removing /tmp/.X11-unix/X$opt{'-kill'}\n"; |
757 | unlink "/tmp/.X11-unix/X$opt{'-kill'}"; | | 757 | unlink "/tmp/.X11-unix/X$opt{'-kill'}"; |
758 | } | | 758 | } |
759 | if (-e "/tmp/.X$opt{'-kill'}-lock") { | | 759 | if (-e "/tmp/.X$opt{'-kill'}-lock") { |
760 | print "Xvnc did not appear to shut down cleanly."; | | 760 | print "Xvnc did not appear to shut down cleanly."; |
761 | print " Removing /tmp/.X$opt{'-kill'}-lock\n"; | | 761 | print " Removing /tmp/.X$opt{'-kill'}-lock\n"; |
762 | unlink "/tmp/.X$opt{'-kill'}-lock"; | | 762 | unlink "/tmp/.X$opt{'-kill'}-lock"; |
763 | } | | 763 | } |
764 | } | | 764 | } |
765 | | | 765 | |
766 | unlink $pidFile; | | 766 | unlink $pidFile; |
767 | exit; | | 767 | exit; |
768 | } | | 768 | } |
769 | | | 769 | |
770 | | | 770 | |
771 | # | | 771 | # |
772 | # ParseOptions takes a list of possible options and a boolean indicating | | 772 | # ParseOptions takes a list of possible options and a boolean indicating |
773 | # whether the option has a value following, and sets up an associative array | | 773 | # whether the option has a value following, and sets up an associative array |
774 | # %opt of the values of the options given on the command line. It removes all | | 774 | # %opt of the values of the options given on the command line. It removes all |
775 | # the arguments it uses from @ARGV and returns them in @optArgs. | | 775 | # the arguments it uses from @ARGV and returns them in @optArgs. |
776 | # | | 776 | # |
777 | | | 777 | |
778 | sub ParseOptions | | 778 | sub ParseOptions |
779 | { | | 779 | { |
780 | local (@optval) = @_; | | 780 | local (@optval) = @_; |
781 | local ($opt, @opts, %valFollows, @newargs); | | 781 | local ($opt, @opts, %valFollows, @newargs); |
782 | | | 782 | |
783 | while (@optval) { | | 783 | while (@optval) { |
784 | $opt = shift(@optval); | | 784 | $opt = shift(@optval); |
785 | push(@opts,$opt); | | 785 | push(@opts,$opt); |
786 | $valFollows{$opt} = shift(@optval); | | 786 | $valFollows{$opt} = shift(@optval); |
787 | } | | 787 | } |
788 | | | 788 | |
789 | @optArgs = (); | | 789 | @optArgs = (); |
790 | %opt = (); | | 790 | %opt = (); |
791 | | | 791 | |
792 | arg: while (defined($arg = shift(@ARGV))) { | | 792 | arg: while (defined($arg = shift(@ARGV))) { |
793 | foreach $opt (@opts) { | | 793 | foreach $opt (@opts) { |
794 | if ($arg eq $opt) { | | 794 | if ($arg eq $opt) { |
795 | push(@optArgs, $arg); | | 795 | push(@optArgs, $arg); |
796 | if ($valFollows{$opt}) { | | 796 | if ($valFollows{$opt}) { |
797 | if (@ARGV == 0) { | | 797 | if (@ARGV == 0) { |
798 | &Usage(); | | 798 | &Usage(); |
799 | } | | 799 | } |
800 | $opt{$opt} = shift(@ARGV); | | 800 | $opt{$opt} = shift(@ARGV); |
801 | push(@optArgs, $opt{$opt}); | | 801 | push(@optArgs, $opt{$opt}); |
802 | } else { | | 802 | } else { |
803 | $opt{$opt} = 1; | | 803 | $opt{$opt} = 1; |
804 | } | | 804 | } |
805 | next arg; | | 805 | next arg; |
806 | } | | 806 | } |
807 | } | | 807 | } |
808 | push(@newargs,$arg); | | 808 | push(@newargs,$arg); |
809 | } | | 809 | } |
810 | | | 810 | |
811 | @ARGV = @newargs; | | 811 | @ARGV = @newargs; |
812 | } | | 812 | } |
813 | | | 813 | |
814 | | | 814 | |
815 | # Routine to make sure we're operating in a sane environment. | | 815 | # Routine to make sure we're operating in a sane environment. |
816 | sub SanityCheck | | 816 | sub SanityCheck |
817 | { | | 817 | { |
818 | local ($cmd); | | 818 | local ($cmd); |
819 | | | 819 | |
820 | # Get the program name | | 820 | # Get the program name |
821 | ($prog) = ($0 =~ m|([^/]+)$|); | | 821 | ($prog) = ($0 =~ m|([^/]+)$|); |
822 | | | 822 | |
823 | # | | 823 | # |
824 | # Check we have all the commands we'll need on the path. | | 824 | # Check we have all the commands we'll need on the path. |
825 | # | | 825 | # |
826 | | | 826 | |
827 | cmd: | | 827 | cmd: |
828 | foreach $cmd ("uname","xauth") { | | 828 | foreach $cmd ("uname","xauth") { |
829 | for (split(/:/,$ENV{PATH})) { | | 829 | for (split(/:/,$ENV{PATH})) { |
830 | if (-x "$_/$cmd") { | | 830 | if (-x "$_/$cmd") { |
831 | next cmd; | | 831 | next cmd; |
832 | } | | 832 | } |
833 | } | | 833 | } |
834 | die "$prog: couldn't find \"$cmd\" on your PATH.\n"; | | 834 | die "$prog: couldn't find \"$cmd\" on your PATH.\n"; |
835 | } | | 835 | } |
836 | | | 836 | |
837 | if($exedir eq "") { | | 837 | if($exedir eq "") { |
838 | cmd2: | | 838 | cmd2: |
839 | foreach $cmd ("Xvnc","vncpasswd") { | | 839 | foreach $cmd ("Xvnc","vncpasswd") { |
840 | for (split(/:/,$ENV{PATH})) { | | 840 | for (split(/:/,$ENV{PATH})) { |
841 | if (-x "$_/$cmd") { | | 841 | if (-x "$_/$cmd") { |
842 | next cmd2; | | 842 | next cmd2; |
843 | } | | 843 | } |
844 | } | | 844 | } |
845 | die "$prog: couldn't find \"$cmd\" on your PATH.\n"; | | 845 | die "$prog: couldn't find \"$cmd\" on your PATH.\n"; |
846 | } | | 846 | } |
847 | } | | 847 | } |
848 | else { | | 848 | else { |
849 | cmd3: | | 849 | cmd3: |
850 | foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") { | | 850 | foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") { |
851 | for (split(/:/,$ENV{PATH})) { | | 851 | for (split(/:/,$ENV{PATH})) { |
852 | if (-x "$cmd") { | | 852 | if (-x "$cmd") { |
853 | next cmd3; | | 853 | next cmd3; |
854 | } | | 854 | } |
855 | } | | 855 | } |
856 | die "$prog: couldn't find \"$cmd\".\n"; | | 856 | die "$prog: couldn't find \"$cmd\".\n"; |
857 | } | | 857 | } |
858 | } | | 858 | } |
859 | | | 859 | |
860 | if (!defined($ENV{HOME})) { | | 860 | if (!defined($ENV{HOME})) { |
861 | die "$prog: The HOME environment variable is not set.\n"; | | 861 | die "$prog: The HOME environment variable is not set.\n"; |
862 | } | | 862 | } |
863 | | | 863 | |
864 | # | | 864 | # |
865 | # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an | | 865 | # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an |
866 | # eval, and if it fails we try 'require "sys/socket.ph"'. If this fails, | | 866 | # eval, and if it fails we try 'require "sys/socket.ph"'. If this fails, |
867 | # we just guess at the values. If you find perl moaning here, just | | 867 | # we just guess at the values. If you find perl moaning here, just |
868 | # hard-code the values of AF_INET and SOCK_STREAM. You can find these out | | 868 | # hard-code the values of AF_INET and SOCK_STREAM. You can find these out |
869 | # for your platform by looking in /usr/include/sys/socket.h and related | | 869 | # for your platform by looking in /usr/include/sys/socket.h and related |
870 | # files. | | 870 | # files. |
871 | # | | 871 | # |
872 | | | 872 | |
873 | chop($os = `uname`); | | 873 | chop($os = `uname`); |
874 | chop($osrev = `uname -r`); | | 874 | chop($osrev = `uname -r`); |
875 | | | 875 | |
876 | eval 'use Socket'; | | 876 | eval 'use Socket'; |
877 | if ($@) { | | 877 | if ($@) { |
878 | eval 'require "sys/socket.ph"'; | | 878 | eval 'require "sys/socket.ph"'; |
879 | if ($@) { | | 879 | if ($@) { |
880 | if (($os eq "SunOS") && ($osrev !~ /^4/)) { | | 880 | if (($os eq "SunOS") && ($osrev !~ /^4/)) { |
881 | $AF_INET = 2; | | 881 | $AF_INET = 2; |
882 | $SOCK_STREAM = 2; | | 882 | $SOCK_STREAM = 2; |
883 | } else { | | 883 | } else { |
884 | $AF_INET = 2; | | 884 | $AF_INET = 2; |
885 | $SOCK_STREAM = 1; | | 885 | $SOCK_STREAM = 1; |
886 | } | | 886 | } |
887 | } else { | | 887 | } else { |
888 | $AF_INET = &AF_INET; | | 888 | $AF_INET = &AF_INET; |
889 | $SOCK_STREAM = &SOCK_STREAM; | | 889 | $SOCK_STREAM = &SOCK_STREAM; |
890 | } | | 890 | } |
891 | } else { | | 891 | } else { |
892 | $AF_INET = &AF_INET; | | 892 | $AF_INET = &AF_INET; |
893 | $SOCK_STREAM = &SOCK_STREAM; | | 893 | $SOCK_STREAM = &SOCK_STREAM; |
894 | } | | 894 | } |
895 | } | | 895 | } |