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>
72 Print8Address (ARRAY8Ptr Address);
83 static char HexChars[] = "0123456789abcdef";
85 if (buflen < length * 2 + 1)
87 for (i = 0; i < length; i++)
89 *buf++ = HexChars[(data[i] >> 4) & 0xf];
90 *buf++ = HexChars[(data[i]) & 0xf];
102 return FormatBytes (a->data, a->length, buf, buflen);
105 typedef struct _IndirectUsers {
106 struct _IndirectUsers *next;
108 CARD16 connectionType;
109 } IndirectUsersRec, *IndirectUsersPtr;
111 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;
135 ForgetIndirectClient (
136 ARRAY8Ptr clientAddress,
137 CARD16 connectionType)
139 IndirectUsersPtr i, prev;
142 for (i = indirectUsers; i; i = i->next)
144 if (XdmcpARRAY8Equal (clientAddress, &i->client) &&
145 connectionType == i->connectionType)
148 prev->next = i->next;
150 indirectUsers = i->next;
151 XdmcpDisposeARRAY8 (&i->client);
160 ARRAY8Ptr clientAddress,
161 CARD16 connectionType)
165 for (i = indirectUsers; i; i = i->next)
166 if (XdmcpARRAY8Equal (clientAddress, &i->client) &&
167 connectionType == i->connectionType)
172 extern char *NetaddrPort();
175 FormatChooserArgument (
179 unsigned char addr_buf[1024];
180 int addr_len = sizeof (addr_buf);
181 unsigned char result_buf[1024];
185 if (GetChooserAddr (addr_buf, &addr_len) == -1)
187 LogError ((unsigned char *)"Cannot get return address for chooser socket\n");
188 Debug ("Cannot get chooser socket address\n");
191 netfamily = NetaddrFamily((XdmcpNetaddr)addr_buf);
197 ARRAY8Ptr localAddress, getLocalAddress ();
199 port = NetaddrPort((XdmcpNetaddr)addr_buf, &portlen);
200 result_buf[0] = netfamily >> 8;
201 result_buf[1] = netfamily & 0xFF;
202 result_buf[2] = port[0];
203 result_buf[3] = port[1];
204 localAddress = getLocalAddress ();
205 bcopy ((char *)localAddress->data, (char *)result_buf+4, 4);
214 Debug ("Chooser family %d isn't known\n", netfamily);
218 return FormatBytes (result_buf, result_len, buf, len);
221 typedef struct _Choices {
222 struct _Choices *next;
224 CARD16 connectionType;
227 } ChoiceRec, *ChoicePtr;
229 static ChoicePtr choices;
233 ARRAY8Ptr clientAddress,
234 CARD16 connectionType)
236 ChoicePtr c, next, prev;
241 for (c = choices; c; c = next)
244 if (now - c->time > 15)
246 Debug ("Timeout choice\n");
251 XdmcpDisposeARRAY8 (&c->client);
252 XdmcpDisposeARRAY8 (&c->choice);
257 if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
258 connectionType == c->connectionType)
267 RegisterIndirectChoice (
268 ARRAY8Ptr clientAddress,
269 CARD16 connectionType,
276 Debug ("Got indirect choice back (%s)\n", Print8Address(clientAddress));
277 for (c = choices; c; c = c->next) {
278 if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
279 connectionType == c->connectionType) {
291 c = (ChoicePtr) malloc (sizeof (ChoiceRec));
295 c->connectionType = connectionType;
296 if (!XdmcpCopyARRAY8 (clientAddress, &c->client))
304 XdmcpDisposeARRAY8 (&c->choice);
307 if (!XdmcpCopyARRAY8 (choice, &c->choice))
309 XdmcpDisposeARRAY8 (&c->client);
320 Debug("choice=(%s)\n", Print8Address(choice));
327 RemoveIndirectChoice (clientAddress, connectionType)
328 ARRAY8Ptr clientAddress;
329 CARD16 connectionType;
334 for (c = choices; c; c = c->next)
336 if (XdmcpARRAY8Equal (clientAddress, &c->client) &&
337 connectionType == c->connectionType)
340 prev->next = c->next;
343 XdmcpDisposeARRAY8 (&c->client);
344 XdmcpDisposeARRAY8 (&c->choice);
356 CARD16 connectionType,
360 char ***argp, **parseArgs();
363 argp = (char ***) closure;
364 if (addr->length == strlen ("BROADCAST") &&
365 !strncmp ((char *)addr->data, "BROADCAST", addr->length))
367 *argp = parseArgs (*argp, "BROADCAST");
369 else if (FormatARRAY8 (addr, hostbuf, sizeof (hostbuf)))
371 *argp = parseArgs (*argp, hostbuf);
375 ProcessChooserSocket (
382 ARRAY8 clientAddress;
383 CARD16 connectionType;
386 Debug ("Process chooser socket\n");
388 client_fd = accept (fd, (struct sockaddr *)buf, &len);
391 LogError ((unsigned char *)"Cannot accept chooser connection\n");
394 Debug ("Accepted %d\n", client_fd);
396 len = read (client_fd, buf, sizeof (buf));
397 Debug ("Read returns %d\n", len);
400 buffer.data = (BYTE *) buf;
401 buffer.size = sizeof (buf);
404 clientAddress.data = 0;
405 clientAddress.length = 0;
408 if (XdmcpReadARRAY8 (&buffer, &clientAddress) &&
409 XdmcpReadCARD16 (&buffer, &connectionType) &&
410 XdmcpReadARRAY8 (&buffer, &choice))
412 Debug ("Read from chooser succesfully\n");
413 if (!RegisterIndirectChoice (&clientAddress, connectionType, &choice))
414 Debug ("Invalid chooser reply\n");
416 XdmcpDisposeARRAY8 (&clientAddress);
417 XdmcpDisposeARRAY8 (&choice);
421 LogError ((unsigned char *)"Choice response read error %s\n", strerror(errno));
430 char **args, **parseArgs(), **systemEnv();
434 Debug ("RunChooser %s\n", d->name);
435 SetTitle (d->name, "chooser");
436 LoadXloginResources (d);
438 args = parseArgs ((char **) 0, d->chooser);
439 strcpy (buf, "-xdmaddress ");
440 if (FormatChooserArgument (buf + strlen (buf), sizeof (buf) - strlen (buf)))
441 args = parseArgs (args, buf);
442 strcpy (buf, "-clientaddress ");
443 if (FormatARRAY8 (&d->clientAddr, buf + strlen (buf), sizeof (buf) - strlen (buf)))
444 args = parseArgs (args, buf);
445 sprintf (buf, "-connectionType %d", d->connectionType);
446 args = parseArgs (args, buf);
447 ForEachChooserHost (&d->clientAddr,
449 (int (*)()) AddChooserHost,
451 env = systemEnv (d, (char *) 0, (char *) 0);
453 env = setEnv (env, "XAUTHORITY", d->authFile);
455 env = setEnv(env, "XMICONSEARCHPATH", d->pmSearchPath);
457 env = setEnv(env, "XMICONBMSEARCHPATH", d->bmSearchPath);
458 if ( d->language && strlen(d->language) > 0 )
459 env = setEnv(env, "LANG", d->language);
460 if ( d->langList && strlen(d->langList) > 0 )
461 env = setEnv(env, LANGLIST, d->langList);
462 #if !defined (ENABLE_DYNAMIC_LANGLIST)
464 if (languageList && strlen(languageList) > 0 )
465 env = setEnv(env, LANGLIST, languageList);
466 #endif /* ENABLE_DYNAMIC_LANGLIST */
468 env = setEnv(env, "XSETUP", d->setup);
469 if(d->displayType.location == Local)
470 env = setEnv (env, LOCATION, "local");
472 env = setEnv (env, LOCATION, "remote");
475 Debug ("Running %s\n", args[0]);
477 Debug ("Couldn't run %s\n", args[0]);
478 LogError ((unsigned char *)"Cannot execute %s\n", args[0]);
479 exit (REMANAGE_DISPLAY);
486 static char buf[200];
492 for (i = 0; i < (int)Address->length; i++) {
493 sprintf(b, " %d", Address->data[i]);
494 b = buf + strlen(buf);