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