2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
25 * (c) Copyright 1993, 1994 International Business Machines Corp. *
26 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
27 * (c) Copyright 1993, 1994 Novell, Inc. *
30 * $TOG: choose.c /main/5 1997/08/13 11:42:50 kaleb $
32 * Copyright 1990 Massachusetts Institute of Technology
34 * Permission to use, copy, modify, distribute, and sell this software and its
35 * documentation for any purpose is hereby granted without fee, provided that
36 * the above copyright notice appear in all copies and that both that
37 * copyright notice and this permission notice appear in supporting
38 * documentation, and that the name of M.I.T. not be used in advertising or
39 * publicity pertaining to distribution of the software without specific,
40 * written prior permission. M.I.T. makes no representations about the
41 * suitability of this software for any purpose. It is provided "as is"
42 * without express or implied warranty.
44 * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
46 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
47 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
48 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
49 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51 * Author: Keith Packard, MIT X Consortium
57 * xdm interface to chooser program
64 # include <sys/types.h>
65 # include <sys/socket.h>
66 # include <netinet/in.h>
71 static char *Print8Address (ARRAY8Ptr Address);
82 static char HexChars[] = "0123456789abcdef";
84 if (buflen < length * 2 + 1)
86 for (i = 0; i < length; i++)
88 *buf++ = HexChars[(data[i] >> 4) & 0xf];
89 *buf++ = HexChars[(data[i]) & 0xf];
101 return FormatBytes (a->data, a->length, buf, buflen);
104 typedef struct _IndirectUsers {
105 struct _IndirectUsers *next;
107 CARD16 connectionType;
108 } IndirectUsersRec, *IndirectUsersPtr;
110 static IndirectUsersPtr indirectUsers;
113 RememberIndirectClient (
114 ARRAY8Ptr clientAddress,
115 CARD16 connectionType)
119 for (i = indirectUsers; i; i = i->next)
120 if (XdmcpARRAY8Equal (clientAddress, &i->client) &&
121 connectionType == i->connectionType)
123 i = (IndirectUsersPtr) malloc (sizeof (IndirectUsersRec));
124 if (!XdmcpCopyARRAY8 (clientAddress, &i->client))
129 i->connectionType = connectionType;
130 i->next = indirectUsers;
136 ForgetIndirectClient (
137 ARRAY8Ptr clientAddress,
138 CARD16 connectionType)
140 IndirectUsersPtr i, prev;
143 for (i = indirectUsers; i; i = i->next)
145 if (XdmcpARRAY8Equal (clientAddress, &i->client) &&
146 connectionType == i->connectionType)
149 prev->next = i->next;
151 indirectUsers = i->next;
152 XdmcpDisposeARRAY8 (&i->client);
162 ARRAY8Ptr clientAddress,
163 CARD16 connectionType)
167 for (i = indirectUsers; i; i = i->next)
168 if (XdmcpARRAY8Equal (clientAddress, &i->client) &&
169 connectionType == i->connectionType)
174 extern char *NetaddrPort();
177 FormatChooserArgument (
181 unsigned char addr_buf[1024];
182 int addr_len = sizeof (addr_buf);
183 unsigned char result_buf[1024];
187 if (GetChooserAddr (addr_buf, &addr_len) == -1)
189 LogError ((unsigned char *)"Cannot get return address for chooser socket\n");
190 Debug ("Cannot get chooser socket address\n");
193 netfamily = NetaddrFamily((XdmcpNetaddr)addr_buf);
199 ARRAY8Ptr localAddress, getLocalAddress ();
201 port = NetaddrPort((XdmcpNetaddr)addr_buf, &portlen);
202 result_buf[0] = netfamily >> 8;
203 result_buf[1] = netfamily & 0xFF;
204 result_buf[2] = port[0];
205 result_buf[3] = port[1];
206 localAddress = getLocalAddress ();
207 bcopy ((char *)localAddress->data, (char *)result_buf+4, 4);
216 Debug ("Chooser family %d isn't known\n", netfamily);
220 return FormatBytes (result_buf, result_len, buf, len);
223 typedef struct _Choices {
224 struct _Choices *next;
226 CARD16 connectionType;
229 } ChoiceRec, *ChoicePtr;
231 static ChoicePtr choices;
235 ARRAY8Ptr clientAddress,
236 CARD16 connectionType)
238 ChoicePtr c, next, prev;
243 for (c = choices; c; c = next)
246 if (now - c->time > 15)
248 Debug ("Timeout choice\n");
253 XdmcpDisposeARRAY8 (&c->client);
254 XdmcpDisposeARRAY8 (&c->choice);
259 if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
260 connectionType == c->connectionType)
269 RegisterIndirectChoice (
270 ARRAY8Ptr clientAddress,
271 CARD16 connectionType,
278 Debug ("Got indirect choice back (%s)\n", Print8Address(clientAddress));
279 for (c = choices; c; c = c->next) {
280 if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
281 connectionType == c->connectionType) {
293 c = (ChoicePtr) malloc (sizeof (ChoiceRec));
297 c->connectionType = connectionType;
298 if (!XdmcpCopyARRAY8 (clientAddress, &c->client))
306 XdmcpDisposeARRAY8 (&c->choice);
309 if (!XdmcpCopyARRAY8 (choice, &c->choice))
311 XdmcpDisposeARRAY8 (&c->client);
322 Debug("choice=(%s)\n", Print8Address(choice));
329 RemoveIndirectChoice (clientAddress, connectionType)
330 ARRAY8Ptr clientAddress;
331 CARD16 connectionType;
336 for (c = choices; c; c = c->next)
338 if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
339 connectionType == c->connectionType)
342 prev->next = c->next;
345 XdmcpDisposeARRAY8 (&c->client);
346 XdmcpDisposeARRAY8 (&c->choice);
358 CARD16 connectionType,
362 char ***argp, **parseArgs();
365 argp = (char ***) closure;
366 if (addr->length == strlen ("BROADCAST") &&
367 !strncmp ((char *)addr->data, "BROADCAST", addr->length))
369 *argp = parseArgs (*argp, "BROADCAST");
371 else if (FormatARRAY8 (addr, hostbuf, sizeof (hostbuf)))
373 *argp = parseArgs (*argp, hostbuf);
378 ProcessChooserSocket (
385 ARRAY8 clientAddress;
386 CARD16 connectionType;
389 Debug ("Process chooser socket\n");
391 client_fd = accept (fd, (struct sockaddr *)buf, &len);
394 LogError ((unsigned char *)"Cannot accept chooser connection\n");
397 Debug ("Accepted %d\n", client_fd);
399 len = read (client_fd, buf, sizeof (buf));
400 Debug ("Read returns %d\n", len);
403 buffer.data = (BYTE *) buf;
404 buffer.size = sizeof (buf);
407 clientAddress.data = 0;
408 clientAddress.length = 0;
411 if (XdmcpReadARRAY8 (&buffer, &clientAddress) &&
412 XdmcpReadCARD16 (&buffer, &connectionType) &&
413 XdmcpReadARRAY8 (&buffer, &choice))
415 Debug ("Read from chooser succesfully\n");
416 if (!RegisterIndirectChoice (&clientAddress, connectionType, &choice))
417 Debug ("Invalid chooser reply\n");
419 XdmcpDisposeARRAY8 (&clientAddress);
420 XdmcpDisposeARRAY8 (&choice);
424 LogError ((unsigned char *)"Choice response read error %s\n", strerror(errno));
435 char **args, **parseArgs(), **systemEnv();
439 Debug ("RunChooser %s\n", d->name);
440 SetTitle (d->name, "chooser");
441 LoadXloginResources (d);
443 args = parseArgs ((char **) 0, d->chooser);
444 strcpy (buf, "-xdmaddress ");
445 if (FormatChooserArgument (buf + strlen (buf), sizeof (buf) - strlen (buf)))
446 args = parseArgs (args, buf);
447 strcpy (buf, "-clientaddress ");
448 if (FormatARRAY8 (&d->clientAddr, buf + strlen (buf), sizeof (buf) - strlen (buf)))
449 args = parseArgs (args, buf);
450 sprintf (buf, "-connectionType %d", d->connectionType);
451 args = parseArgs (args, buf);
452 ForEachChooserHost (&d->clientAddr,
454 (int (*)()) AddChooserHost,
456 env = systemEnv (d, (char *) 0, (char *) 0);
458 env = setEnv (env, "XAUTHORITY", d->authFile);
460 env = setEnv(env, "XMICONSEARCHPATH", d->pmSearchPath);
462 env = setEnv(env, "XMICONBMSEARCHPATH", d->bmSearchPath);
463 if ( d->language && strlen(d->language) > 0 )
464 env = setEnv(env, "LANG", d->language);
465 if ( d->langList && strlen(d->langList) > 0 )
466 env = setEnv(env, LANGLIST, d->langList);
467 #if !defined (ENABLE_DYNAMIC_LANGLIST)
469 if ( strlen(languageList) > 0 )
470 env = setEnv(env, LANGLIST, languageList);
471 #endif /* ENABLE_DYNAMIC_LANGLIST */
473 env = setEnv(env, "XSETUP", d->setup);
474 if(d->displayType.location == Local)
475 env = setEnv (env, LOCATION, "local");
477 env = setEnv (env, LOCATION, "remote");
480 Debug ("Running %s\n", args[0]);
482 Debug ("Couldn't run %s\n", args[0]);
483 LogError ((unsigned char *)"Cannot execute %s\n", args[0]);
484 exit (REMANAGE_DISPLAY);
491 static char buf[200];
497 for (i = 0; i < (int)Address->length; i++) {
498 sprintf(b, " %d", Address->data[i]);
499 b = buf + strlen(buf);