file.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  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)
  10. * any later version.
  11. *
  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
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* *
  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. *
  28. */
  29. /*
  30. * xdm - display manager daemon
  31. *
  32. * $XConsortium: file.c /main/4 1995/10/27 16:13:19 rswiston $
  33. *
  34. * Copyright 1988 Massachusetts Institute of Technology
  35. *
  36. * Permission to use, copy, modify, and distribute this software and its
  37. * documentation for any purpose and without fee is hereby granted, provided
  38. * that the above copyright notice appear in all copies and that both that
  39. * copyright notice and this permission notice appear in supporting
  40. * documentation, and that the name of M.I.T. not be used in advertising or
  41. * publicity pertaining to distribution of the software without specific,
  42. * written prior permission. M.I.T. makes no representations about the
  43. * suitability of this software for any purpose. It is provided "as is"
  44. * without express or implied warranty.
  45. *
  46. * Author: Keith Packard, MIT X Consortium
  47. */
  48. /*
  49. * file.c
  50. */
  51. # include "dm.h"
  52. # include "vgmsg.h"
  53. # include <ctype.h>
  54. # include <signal.h>
  55. # include <pwd.h>
  56. # include <sys/socket.h>
  57. # include <netinet/in.h>
  58. # include <netdb.h>
  59. /***************************************************************************
  60. *
  61. * Local procedure declarations
  62. *
  63. ***************************************************************************/
  64. static int DisplayTypeMatch( DisplayType d1, DisplayType d2) ;
  65. static void freeArgs( char **args) ;
  66. static void freeSomeArgs( char **args, int n) ;
  67. static DisplayType parseDisplayType( char *string, int *usedDefaultType, int *parse_uid) ;
  68. static char ** splitIntoWords( char *s) ;
  69. static char ** copyArgs( char **args) ;
  70. /***************************************************************************
  71. *
  72. * main
  73. *
  74. ***************************************************************************/
  75. static int
  76. DisplayTypeMatch( DisplayType d1, DisplayType d2 )
  77. {
  78. return d1.location == d2.location &&
  79. d1.lifetime == d2.lifetime &&
  80. d1.origin == d2.origin;
  81. }
  82. static void
  83. freeArgs( char **args )
  84. {
  85. char **a;
  86. for (a = args; *a; a++)
  87. free (*a);
  88. free ((char *) args);
  89. }
  90. static char **
  91. splitIntoWords( char *s )
  92. {
  93. char **args, **newargs;
  94. char *wordStart;
  95. int nargs;
  96. args = 0;
  97. nargs = 0;
  98. while (*s)
  99. {
  100. while (*s && isspace (*s))
  101. ++s;
  102. if (!*s || *s == '#')
  103. break;
  104. wordStart = s;
  105. while (*s && *s != '#' && !isspace (*s))
  106. ++s;
  107. if (!args)
  108. {
  109. args = (char **) malloc (2 * sizeof (char *));
  110. if (!args)
  111. return NULL;
  112. }
  113. else
  114. {
  115. newargs = (char **) realloc ((char *) args,
  116. (nargs+2)*sizeof (char *));
  117. if (!newargs)
  118. {
  119. freeArgs (args);
  120. return NULL;
  121. }
  122. args = newargs;
  123. }
  124. args[nargs] = malloc (s - wordStart + 1);
  125. if (!args[nargs])
  126. {
  127. freeArgs (args);
  128. return NULL;
  129. }
  130. strncpy (args[nargs], wordStart, s - wordStart);
  131. args[nargs][s-wordStart] = '\0';
  132. ++nargs;
  133. args[nargs] = NULL;
  134. }
  135. return args;
  136. }
  137. static char **
  138. copyArgs( char **args )
  139. {
  140. char **a, **new, **n;
  141. for (a = args; *a; a++)
  142. ;
  143. new = (char **) malloc ((a - args + 1) * sizeof (char *));
  144. if (!new)
  145. return NULL;
  146. n = new;
  147. a = args;
  148. while (*n++ = *a++)
  149. ;
  150. return new;
  151. }
  152. static void
  153. freeSomeArgs( char **args, int n )
  154. {
  155. char **a;
  156. a = args;
  157. while (n--)
  158. free (*a++);
  159. free ((char *) args);
  160. }
  161. int
  162. ParseDisplay( char *source,
  163. DisplayType *acceptableTypes,
  164. int numAcceptable,
  165. struct passwd *puser)
  166. {
  167. char **args, **argv, **a;
  168. char *name = NULL, *class, *type;
  169. struct display *d;
  170. int usedDefaultType;
  171. int parse_uid;
  172. DisplayType displayType;
  173. char *device=NULL; /* ITE device associated with display */
  174. args = splitIntoWords (source);
  175. if (!args)
  176. return 0;
  177. if (!args[0])
  178. {
  179. LogError(ReadCatalog(MC_LOG_SET,MC_LOG_MISS_NAME,MC_DEF_LOG_MISS_NAME));
  180. freeArgs (args);
  181. return 0;
  182. }
  183. name = strdup(args[0]);
  184. if (!args[1])
  185. {
  186. LogError(ReadCatalog(MC_LOG_SET,MC_LOG_MISS_TYPE,MC_DEF_LOG_MISS_TYPE),
  187. args[0]);
  188. freeArgs (args);
  189. free(name);
  190. return 0;
  191. }
  192. /*
  193. * strip off display device if found in second field...
  194. */
  195. if ( (device = strchr(args[1],'@')) != NULL) {
  196. *device = '\0';
  197. device++;
  198. }
  199. displayType = parseDisplayType (args[1], &usedDefaultType, &parse_uid);
  200. class = NULL;
  201. type = args[1];
  202. argv = args + 2;
  203. /*
  204. * check for special syntax "*" and expand to host name.
  205. * if hostname cannot be found in a database, assume invalid and
  206. * delete.
  207. */
  208. if ( strcmp(name, "*") == 0) {
  209. char tname[128];
  210. struct hostent *hostent;
  211. memset(tname, 0, 128);
  212. gethostname(tname, 128 - 1);
  213. if ( (hostent = gethostbyname(tname)) == NULL ) {
  214. LogError(
  215. ReadCatalog(MC_LOG_SET,MC_LOG_INV_HOSTNM,MC_DEF_LOG_INV_HOSTNM),
  216. tname);
  217. tname[0] = 0;
  218. }
  219. strncat(tname, ":0", 128 - 1);
  220. free(name);
  221. name = strdup(tname);
  222. }
  223. /*
  224. * extended syntax; if the second argument doesn't
  225. * exactly match a legal display type and the third
  226. * argument does, use the second argument as the
  227. * display class string
  228. */
  229. if (usedDefaultType && args[2])
  230. {
  231. /*
  232. * strip off display device if found in third field...
  233. */
  234. if ( device == NULL && (device = strchr(args[2],'@')) != NULL) {
  235. *device = '\0';
  236. device++;
  237. }
  238. displayType = parseDisplayType (args[2], &usedDefaultType, &parse_uid);
  239. if (!usedDefaultType)
  240. {
  241. class = args[1];
  242. type = args[2];
  243. argv = args + 3;
  244. }
  245. }
  246. /*
  247. * extended syntax; if the display type argument was
  248. * "local_uid", then next argument is pseudo user id
  249. * under which the local Xserver is to be run.
  250. */
  251. if (parse_uid) {
  252. struct passwd *p;
  253. Debug("Xservers 'local_uid' pseudo user = %s\n", *argv);
  254. if ( (p = getpwnam (*argv)) != NULL) {
  255. *puser = *p;
  256. } else {
  257. Debug("Could not get password entry for user name '%s'\n", *argv);
  258. Debug("Using default pseudo user = %s\n", puser->pw_name);
  259. }
  260. argv = argv + 1;
  261. } else {
  262. Debug("Default pseudo user = %s\n", puser->pw_name);
  263. }
  264. while (numAcceptable)
  265. {
  266. if (DisplayTypeMatch (*acceptableTypes, displayType))
  267. break;
  268. --numAcceptable;
  269. ++acceptableTypes;
  270. }
  271. if (!numAcceptable)
  272. {
  273. LogError(ReadCatalog(
  274. MC_LOG_SET,MC_LOG_BAD_DPYTYPE,MC_DEF_LOG_BAD_DPYTYPE),
  275. type, name);
  276. }
  277. /*
  278. * see if this display is already being managed...
  279. */
  280. d = FindDisplayByName (name);
  281. if (d)
  282. {
  283. d->state = OldEntry;
  284. if (class && strcmp (d->class, class))
  285. {
  286. char *newclass;
  287. newclass = malloc ((unsigned) (strlen (class) + 1));
  288. if (newclass)
  289. {
  290. free (d->class);
  291. strcpy (newclass, class);
  292. d->class = newclass;
  293. }
  294. }
  295. Debug ("Found existing display: %s %s %s", d->name, d->class ? d->class : "", type);
  296. freeArgs (d->argv);
  297. }
  298. else
  299. {
  300. d = NewDisplay (name, class);
  301. Debug ("Found new display: %s %s %s", d->name, d->class ? d->class : "", type);
  302. }
  303. d->displayType = displayType;
  304. d->argv = copyArgs (argv);
  305. for (a = d->argv; a && *a; a++)
  306. Debug (" %s", *a);
  307. Debug ("\n");
  308. /*
  309. * add device to display information...
  310. */
  311. if ( device != NULL && strlen(device) != 0 ) {
  312. if (d->gettyLine != NULL)
  313. free(d->gettyLine);
  314. d->gettyLine = strdup(device);
  315. }
  316. if (d->gettyLine &&
  317. (strcmp(d->gettyLine, "None") == 0 ||
  318. strcmp(d->gettyLine, "none") == 0 ) ) {
  319. strcpy(d->gettyLine,"??");
  320. }
  321. freeSomeArgs (args, argv - args);
  322. free(name);
  323. return 1;
  324. }
  325. static struct displayMatch {
  326. char *name;
  327. DisplayType type;
  328. } displayTypes[] = {
  329. "local", { Local, Permanent, FromFile },
  330. "local_uid", { Local, Permanent, FromFile },
  331. "foreign", { Foreign, Permanent, FromFile },
  332. 0, { Local, Permanent, FromFile },
  333. };
  334. static DisplayType
  335. parseDisplayType( char *string, int *usedDefaultType, int *parse_uid )
  336. {
  337. struct displayMatch *d;
  338. *parse_uid = 0;
  339. for (d = displayTypes; d->name; d++) {
  340. if (strcmp(d->name, string) == 0)
  341. {
  342. if (strcmp(d->name, "local_uid") == 0) {
  343. *parse_uid = 1;
  344. }
  345. *usedDefaultType = 0;
  346. return d->type;
  347. }
  348. }
  349. *usedDefaultType = 1;
  350. return d->type;
  351. }