dtprintinfo: Coverity 89561
[oweals/cde.git] / cde / programs / dtlogin / file.c
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 /*
50  * file.c
51  */
52
53 # include       "dm.h"
54 # include       "vgmsg.h"
55 # include       <ctype.h>
56 # include       <signal.h>
57 # include       <pwd.h>
58
59 # include       <sys/socket.h>
60 # include       <netinet/in.h>
61 # include       <netdb.h>
62
63
64
65 /***************************************************************************
66  *
67  *  Local procedure declarations
68  *
69  ***************************************************************************/
70
71 static int DisplayTypeMatch( DisplayType d1, DisplayType d2) ;
72 static void freeArgs( char **args) ;
73 static void freeSomeArgs( char **args, int n) ;
74 static DisplayType parseDisplayType( char *string, int *usedDefaultType, int *parse_uid) ;
75 static char ** splitIntoWords( char *s) ;
76 static char ** copyArgs( char **args) ;
77
78
79
80
81 /***************************************************************************
82  *
83  *  main
84  *
85  ***************************************************************************/
86
87 static int 
88 DisplayTypeMatch( DisplayType d1, DisplayType d2 )
89 {
90         return d1.location == d2.location &&
91                d1.lifetime == d2.lifetime &&
92                d1.origin == d2.origin;
93 }
94
95 static void 
96 freeArgs( char **args )
97 {
98     char    **a;
99
100     for (a = args; *a; a++)
101         free (*a);
102     free ((char *) args);
103 }
104
105 static char ** 
106 splitIntoWords( char *s )
107 {
108     char    **args, **newargs;
109     char    *wordStart;
110     int     nargs;
111
112     args = 0;
113     nargs = 0;
114     while (*s)
115     {
116         while (*s && isspace (*s))
117             ++s;
118         if (!*s || *s == '#')
119             break;
120         wordStart = s;
121         while (*s && *s != '#' && !isspace (*s))
122             ++s;
123         if (!args)
124         {
125             args = (char **) malloc (2 * sizeof (char *));
126             if (!args)
127                 return NULL;
128         }
129         else
130         {
131             newargs = (char **) realloc ((char *) args,
132                                          (nargs+2)*sizeof (char *));
133             if (!newargs)
134             {
135                 freeArgs (args);
136                 return NULL;
137             }
138             args = newargs;
139         }
140         args[nargs] = malloc (s - wordStart + 1);
141         if (!args[nargs])
142         {
143             freeArgs (args);
144             return NULL;
145         }
146         strncpy (args[nargs], wordStart, s - wordStart);
147         args[nargs][s-wordStart] = '\0';
148         ++nargs;
149         args[nargs] = NULL;
150     }
151     return args;
152 }
153
154 static char ** 
155 copyArgs( char **args )
156 {
157     char    **a, **new, **n;
158
159     for (a = args; *a; a++)
160         ;
161     new = (char **) malloc ((a - args + 1) * sizeof (char *));
162     if (!new)
163         return NULL;
164     n = new;
165     a = args;
166     while (*n++ = *a++)
167         ;
168     return new;
169 }
170
171 static void 
172 freeSomeArgs( char **args, int n )
173 {
174     char    **a;
175
176     a = args;
177     while (n--)
178         free (*a++);
179     free ((char *) args);
180 }
181
182 int 
183 ParseDisplay( char *source, 
184               DisplayType *acceptableTypes, 
185               int numAcceptable,
186               struct passwd *puser)
187 {
188     char                **args, **argv, **a;
189     char                *name = NULL, *class, *type;
190     struct display      *d;
191     int                 usedDefaultType;
192     int                 parse_uid;
193     DisplayType         displayType;
194
195     char                *device=NULL; /* ITE device associated with display */
196
197
198     args = splitIntoWords (source);
199     if (!args)
200         return 0;
201     if (!args[0])
202     {
203         LogError(ReadCatalog(MC_LOG_SET,MC_LOG_MISS_NAME,MC_DEF_LOG_MISS_NAME));
204         freeArgs (args);
205         return 0;
206     }
207     name = strdup(args[0]);
208     if (!args[1])
209     {
210         LogError(ReadCatalog(MC_LOG_SET,MC_LOG_MISS_TYPE,MC_DEF_LOG_MISS_TYPE),
211                 args[0]);
212         freeArgs (args);
213         free(name);
214         return 0;
215     }
216
217     /*
218      *  strip off display device if found in second field...
219      */
220
221     if ( (device = strchr(args[1],'@')) != NULL) {
222         *device = '\0';
223         device++;
224     }
225         
226     displayType = parseDisplayType (args[1], &usedDefaultType, &parse_uid);
227     class = NULL;
228     type = args[1];
229     argv = args + 2;
230
231     /*
232      *  check for special syntax "*" and expand to host name.
233      *  if hostname cannot be found in a database, assume invalid and
234      *  delete.
235      */
236     if ( strcmp(name, "*") == 0) {
237         char            tname[128];
238         struct hostent  *hostent;
239
240         memset(tname, 0, 128);
241         gethostname(tname, 128 - 1);
242         if ( (hostent = gethostbyname(tname)) == NULL ) {
243             LogError(
244                 ReadCatalog(MC_LOG_SET,MC_LOG_INV_HOSTNM,MC_DEF_LOG_INV_HOSTNM),
245                       tname);
246             tname[0] = 0;
247         }
248
249         strncat(tname, ":0", 128 - 1);
250         
251         free(name);
252         name = strdup(tname);
253     }
254
255     /*
256      * extended syntax; if the second argument doesn't
257      * exactly match a legal display type and the third
258      * argument does, use the second argument as the
259      * display class string
260      */
261     if (usedDefaultType && args[2])
262     {
263
264         /*
265          *  strip off display device if found in third field...
266          */
267
268         if ( device == NULL && (device = strchr(args[2],'@')) != NULL) {
269             *device = '\0';
270             device++;
271         }
272
273         displayType = parseDisplayType (args[2], &usedDefaultType, &parse_uid);
274         if (!usedDefaultType)
275         {
276             class = args[1];
277             type = args[2];
278             argv = args + 3;
279         }
280     }
281     /*
282      * extended syntax; if the display type argument was 
283      * "local_uid", then next argument is pseudo user id
284      * under which the local Xserver is to be run.
285      */
286     if (parse_uid) {
287         struct passwd *p;
288
289         Debug("Xservers 'local_uid' pseudo user = %s\n", *argv);
290
291         if ( (p = getpwnam (*argv)) != NULL) {
292             *puser = *p;
293         } else {
294             Debug("Could not get password entry for user name '%s'\n", *argv);
295             Debug("Using default pseudo user = %s\n", puser->pw_name);
296         }
297
298         argv = argv + 1;
299     } else {
300         Debug("Default pseudo user = %s\n", puser->pw_name);
301     }
302
303     while (numAcceptable)
304     {
305         if (DisplayTypeMatch (*acceptableTypes, displayType))
306             break;
307         --numAcceptable;
308         ++acceptableTypes;
309     }
310     if (!numAcceptable)
311     {
312         LogError(ReadCatalog(
313                 MC_LOG_SET,MC_LOG_BAD_DPYTYPE,MC_DEF_LOG_BAD_DPYTYPE),
314                   type, name);
315     }
316
317
318     /*
319      *  see if this display is already being managed...
320      */
321
322     d = FindDisplayByName (name);
323     if (d)
324     {
325         d->state = OldEntry;
326         if (class && strcmp (d->class, class))
327         {
328             char    *newclass;
329
330             newclass = malloc ((unsigned) (strlen (class) + 1));
331             if (newclass)
332             {
333                 free (d->class);
334                 strcpy (newclass, class);
335                 d->class = newclass;
336             }
337         }
338         Debug ("Found existing display:  %s %s %s", d->name, d->class ? d->class : "", type);
339         freeArgs (d->argv);
340     }
341     else
342     {
343         d = NewDisplay (name, class);
344         Debug ("Found new display:  %s %s %s", d->name, d->class ? d->class : "", type);
345     }
346     d->displayType = displayType;
347     d->argv = copyArgs (argv);
348     for (a = d->argv; a && *a; a++)
349         Debug (" %s", *a);
350     Debug ("\n");
351
352     /*
353      * add device to display information...
354      */
355      
356     if ( device != NULL && strlen(device) != 0 ) {
357         if (d->gettyLine != NULL)
358             free(d->gettyLine);
359
360         d->gettyLine = strdup(device);
361
362     }
363
364     if (d->gettyLine && 
365         (strcmp(d->gettyLine, "None") == 0 ||
366          strcmp(d->gettyLine, "none") == 0   ) ) {
367
368         strcpy(d->gettyLine,"??");
369     }
370
371
372     freeSomeArgs (args, argv - args);
373     free(name);
374
375     return 1;
376 }
377
378 static struct displayMatch {
379         char            *name;
380         DisplayType     type;
381 } displayTypes[] = {
382         "local",                { Local, Permanent, FromFile },
383         "local_uid",            { Local, Permanent, FromFile },
384         "foreign",              { Foreign, Permanent, FromFile },
385         0,                      { Local, Permanent, FromFile },
386 };
387
388 static DisplayType 
389 parseDisplayType( char *string, int *usedDefaultType, int *parse_uid )
390 {
391         struct displayMatch     *d;
392
393         *parse_uid = 0;
394
395         for (d = displayTypes; d->name; d++) {
396             if (strcmp(d->name, string) == 0)
397             {
398                 if (strcmp(d->name, "local_uid") == 0) {
399                    *parse_uid = 1; 
400                 }
401                 *usedDefaultType = 0;
402                 return d->type;
403             }
404         }
405
406         *usedDefaultType = 1;
407         return d->type;
408 }