file.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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 librararies 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, *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 = 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. return 0;
  190. }
  191. /*
  192. * strip off display device if found in second field...
  193. */
  194. if ( (device = strchr(args[1],'@')) != NULL) {
  195. *device = '\0';
  196. device++;
  197. }
  198. displayType = parseDisplayType (args[1], &usedDefaultType, &parse_uid);
  199. class = NULL;
  200. type = args[1];
  201. argv = args + 2;
  202. /*
  203. * check for special syntax "*" and expand to host name.
  204. * if hostname cannot be found in a database, assume invalid and
  205. * delete.
  206. */
  207. if ( strcmp(name, "*") == 0) {
  208. char tname[128];
  209. struct hostent *hostent;
  210. strcpy(tname,"");
  211. gethostname(tname, sizeof(tname));
  212. if ( (hostent = gethostbyname(tname)) == NULL ) {
  213. LogError(
  214. ReadCatalog(MC_LOG_SET,MC_LOG_INV_HOSTNM,MC_DEF_LOG_INV_HOSTNM),
  215. tname);
  216. strcpy(tname,"");
  217. }
  218. /*
  219. else
  220. strcpy(tname,hostent->h_name);
  221. */
  222. strcat(tname, ":0");
  223. name = tname;
  224. }
  225. /*
  226. * extended syntax; if the second argument doesn't
  227. * exactly match a legal display type and the third
  228. * argument does, use the second argument as the
  229. * display class string
  230. */
  231. if (usedDefaultType && args[2])
  232. {
  233. /*
  234. * strip off display device if found in third field...
  235. */
  236. if ( device == NULL && (device = strchr(args[2],'@')) != NULL) {
  237. *device = '\0';
  238. device++;
  239. }
  240. displayType = parseDisplayType (args[2], &usedDefaultType, &parse_uid);
  241. if (!usedDefaultType)
  242. {
  243. class = args[1];
  244. type = args[2];
  245. argv = args + 3;
  246. }
  247. }
  248. /*
  249. * extended syntax; if the display type argument was
  250. * "local_uid", then next argument is pseudo user id
  251. * under which the local Xserver is to be run.
  252. */
  253. if (parse_uid) {
  254. struct passwd *p;
  255. Debug("Xservers 'local_uid' pseudo user = %s\n", *argv);
  256. if ( (p = getpwnam (*argv)) != NULL) {
  257. *puser = *p;
  258. } else {
  259. Debug("Could not get password entry for user name '%s'\n", *argv);
  260. Debug("Using default pseudo user = %s\n", puser->pw_name);
  261. }
  262. argv = argv + 1;
  263. } else {
  264. Debug("Default pseudo user = %s\n", puser->pw_name);
  265. }
  266. while (numAcceptable)
  267. {
  268. if (DisplayTypeMatch (*acceptableTypes, displayType))
  269. break;
  270. --numAcceptable;
  271. ++acceptableTypes;
  272. }
  273. if (!numAcceptable)
  274. {
  275. LogError(ReadCatalog(
  276. MC_LOG_SET,MC_LOG_BAD_DPYTYPE,MC_DEF_LOG_BAD_DPYTYPE),
  277. type, name);
  278. }
  279. /*
  280. * see if this display is already being managed...
  281. */
  282. d = FindDisplayByName (name);
  283. if (d)
  284. {
  285. d->state = OldEntry;
  286. if (class && strcmp (d->class, class))
  287. {
  288. char *newclass;
  289. newclass = malloc ((unsigned) (strlen (class) + 1));
  290. if (newclass)
  291. {
  292. free (d->class);
  293. strcpy (newclass, class);
  294. d->class = newclass;
  295. }
  296. }
  297. Debug ("Found existing display: %s %s %s", d->name, d->class ? d->class : "", type);
  298. freeArgs (d->argv);
  299. }
  300. else
  301. {
  302. d = NewDisplay (name, class);
  303. Debug ("Found new display: %s %s %s", d->name, d->class ? d->class : "", type);
  304. }
  305. d->displayType = displayType;
  306. d->argv = copyArgs (argv);
  307. for (a = d->argv; a && *a; a++)
  308. Debug (" %s", *a);
  309. Debug ("\n");
  310. /*
  311. * add device to display information...
  312. */
  313. if ( device != NULL && strlen(device) != 0 ) {
  314. if (d->gettyLine != NULL)
  315. free(d->gettyLine);
  316. d->gettyLine = strdup(device);
  317. }
  318. if (d->gettyLine &&
  319. (strcmp(d->gettyLine, "None") == 0 ||
  320. strcmp(d->gettyLine, "none") == 0 ) ) {
  321. strcpy(d->gettyLine,"??");
  322. }
  323. freeSomeArgs (args, argv - args);
  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. }