Home | History | Annotate | Line # | Download | only in xdm
      1 /*
      2 
      3 Copyright 1988, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included
     12 in all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     16 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     17 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 OTHER DEALINGS IN THE SOFTWARE.
     21 
     22 Except as contained in this notice, the name of The Open Group shall
     23 not be used in advertising or otherwise to promote the sale, use or
     24 other dealings in this Software without prior written authorization
     25 from The Open Group.
     26 
     27 */
     28 
     29 /*
     30  * xdm - display manager daemon
     31  * Author:  Keith Packard, MIT X Consortium
     32  *
     33  * file.c
     34  */
     35 
     36 #include	"dm.h"
     37 #include	"dm_error.h"
     38 
     39 #include	<ctype.h>
     40 
     41 static int
     42 DisplayTypeMatch (DisplayType d1, DisplayType d2)
     43 {
     44 	return d1.location == d2.location &&
     45 	       d1.lifetime == d2.lifetime &&
     46 	       d1.origin == d2.origin;
     47 }
     48 
     49 static void
     50 freeFileArgs (char **args)
     51 {
     52     char    **a;
     53 
     54     for (a = args; *a; a++)
     55 	free (*a);
     56     free (args);
     57 }
     58 
     59 static char **
     60 splitIntoWords (char *s)
     61 {
     62     char    **args, **newargs;
     63     char    *wordStart;
     64     int	    nargs;
     65 
     66     args = NULL;
     67     nargs = 0;
     68     while (*s)
     69     {
     70 	while (*s && isspace (*s))
     71 	    ++s;
     72 	if (!*s || *s == '#')
     73 	    break;
     74 	wordStart = s;
     75 	while (*s && *s != '#' && !isspace (*s))
     76 	    ++s;
     77 	if (!args)
     78 	{
     79 	    args = malloc (2 * sizeof (char *));
     80 	    if (!args)
     81 		return NULL;
     82 	}
     83 	else
     84 	{
     85 	    newargs = realloc ((char *) args, (nargs+2)*sizeof (char *));
     86 	    if (!newargs)
     87 	    {
     88 		freeFileArgs (args);
     89 		return NULL;
     90 	    }
     91 	    args = newargs;
     92 	}
     93 	args[nargs] = malloc (s - wordStart + 1);
     94 	if (!args[nargs])
     95 	{
     96 	    freeFileArgs (args);
     97 	    return NULL;
     98 	}
     99 	strncpy (args[nargs], wordStart, s - wordStart);
    100 	args[nargs][s-wordStart] = '\0';
    101 	++nargs;
    102 	args[nargs] = NULL;
    103     }
    104     return args;
    105 }
    106 
    107 static char **
    108 copyArgs (char **args)
    109 {
    110     char    **a, **new, **n;
    111 
    112     for (a = args; *a; a++)
    113 	/* SUPPRESS 530 */
    114 	;
    115     new = malloc ((a - args + 1) * sizeof (char *));
    116     if (!new)
    117 	return NULL;
    118     n = new;
    119     a = args;
    120     /* SUPPRESS 560 */
    121     while ((*n++ = *a++))
    122 	/* SUPPRESS 530 */
    123 	;
    124     return new;
    125 }
    126 
    127 static void
    128 freeSomeArgs (char **args, int n)
    129 {
    130     char    **a;
    131 
    132     a = args;
    133     while (n--)
    134 	free (*a++);
    135     free (args);
    136 }
    137 
    138 void
    139 ParseDisplay (char *source, DisplayType *acceptableTypes, int numAcceptable)
    140 {
    141     char		**args, **argv, **a;
    142     char		*name, *class, *type;
    143     struct display	*d;
    144     int			usedDefault;
    145     DisplayType		displayType;
    146 
    147     args = splitIntoWords (source);
    148     if (!args)
    149 	return;
    150     if (!args[0])
    151     {
    152 	LogError ("Missing display name in servers file\n");
    153 	freeFileArgs (args);
    154 	return;
    155     }
    156     name = args[0];
    157     if (!args[1])
    158     {
    159 	LogError ("Missing display type for %s\n", args[0]);
    160 	freeFileArgs (args);
    161 	return;
    162     }
    163     displayType = parseDisplayType (args[1], &usedDefault);
    164     class = NULL;
    165     type = args[1];
    166     argv = args + 2;
    167     /*
    168      * extended syntax; if the second argument doesn't
    169      * exactly match a legal display type and the third
    170      * argument does, use the second argument as the
    171      * display class string
    172      */
    173     if (usedDefault && args[2])
    174     {
    175 	displayType = parseDisplayType (args[2], &usedDefault);
    176 	if (!usedDefault)
    177 	{
    178 	    class = args[1];
    179 	    type = args[2];
    180 	    argv = args + 3;
    181 	}
    182     }
    183     while (numAcceptable)
    184     {
    185 	if (DisplayTypeMatch (*acceptableTypes, displayType))
    186 	    break;
    187 	--numAcceptable;
    188 	++acceptableTypes;
    189     }
    190     if (!numAcceptable)
    191     {
    192 	LogError ("Unacceptable display type %s for display %s\n",
    193 		  type, name);
    194     }
    195     d = FindDisplayByName (name);
    196     if (d)
    197     {
    198 	d->state = OldEntry;
    199 	if (class && strcmp (d->class, class))
    200 	{
    201 	    char    *newclass;
    202 
    203 	    newclass = strdup (class);
    204 	    if (newclass)
    205 	    {
    206 		free (d->class);
    207 		d->class = newclass;
    208 	    }
    209 	}
    210 	Debug ("Found existing display:  %s %s %s", d->name, d->class , type);
    211 	freeFileArgs (d->argv);
    212     }
    213     else
    214     {
    215 	d = NewDisplay (name, class);
    216 	Debug ("Found new display:  %s %s %s",
    217 		d->name, d->class ? d->class : "", type);
    218     }
    219     d->displayType = displayType;
    220     d->argv = copyArgs (argv);
    221     for (a = d->argv; a && *a; a++)
    222 	Debug (" %s", *a);
    223     Debug ("\n");
    224     freeSomeArgs (args, argv - args);
    225 }
    226 
    227 static struct displayMatch {
    228 	const char	*name;
    229 	DisplayType	type;
    230 } displayTypes[] = {
    231 	{ "local",		{ Local, Permanent, FromFile } },
    232 	{ "foreign",		{ Foreign, Permanent, FromFile } },
    233 	{ NULL,			{ Local, Permanent, FromFile } },
    234 };
    235 
    236 DisplayType
    237 parseDisplayType (char *string, int *usedDefault)
    238 {
    239 	struct displayMatch	*d;
    240 
    241 	for (d = displayTypes; d->name; d++)
    242 		if (!strcmp (d->name, string))
    243 		{
    244 			*usedDefault = 0;
    245 			return d->type;
    246 		}
    247 	*usedDefault = 1;
    248 	return d->type;
    249 }
    250