Use C++ linker
[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 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 /*
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, *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;
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;
206     }
207     name = 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         return;
214     }
215
216     /*
217      *  strip off display device if found in second field...
218      */
219
220     if ( (device = strchr(args[1],'@')) != NULL) {
221         *device = '\0';
222         device++;
223     }
224         
225     displayType = parseDisplayType (args[1], &usedDefaultType, &parse_uid);
226     class = NULL;
227     type = args[1];
228     argv = args + 2;
229
230     /*
231      *  check for special syntax "*" and expand to host name.
232      *  if hostname cannot be found in a database, assume invalid and
233      *  delete.
234      */
235     if ( strcmp(name, "*") == 0) {
236         char            tname[128];
237         struct hostent  *hostent;
238
239         strcpy(tname,"");
240         gethostname(tname, sizeof(tname));
241         if ( (hostent = gethostbyname(tname)) == NULL ) {
242             LogError(
243                 ReadCatalog(MC_LOG_SET,MC_LOG_INV_HOSTNM,MC_DEF_LOG_INV_HOSTNM),
244                       tname);
245             strcpy(tname,"");
246         }
247 /*
248         else
249             strcpy(tname,hostent->h_name);
250 */
251
252         strcat(tname, ":0");
253         
254         name = tname;
255     }
256
257     /*
258      * extended syntax; if the second argument doesn't
259      * exactly match a legal display type and the third
260      * argument does, use the second argument as the
261      * display class string
262      */
263     if (usedDefaultType && args[2])
264     {
265
266         /*
267          *  strip off display device if found in third field...
268          */
269
270         if ( device == NULL && (device = strchr(args[2],'@')) != NULL) {
271             *device = '\0';
272             device++;
273         }
274
275         displayType = parseDisplayType (args[2], &usedDefaultType, &parse_uid);
276         if (!usedDefaultType)
277         {
278             class = args[1];
279             type = args[2];
280             argv = args + 3;
281         }
282     }
283     /*
284      * extended syntax; if the display type argument was 
285      * "local_uid", then next argument is pseudo user id
286      * under which the local Xserver is to be run.
287      */
288     if (parse_uid) {
289         struct passwd *p;
290
291         Debug("Xservers 'local_uid' pseudo user = %s\n", *argv);
292
293         if ( (p = getpwnam (*argv)) != NULL) {
294             *puser = *p;
295         } else {
296             Debug("Could not get password entry for user name '%s'\n", *argv);
297             Debug("Using default pseudo user = %s\n", puser->pw_name);
298         }
299
300         argv = argv + 1;
301     } else {
302         Debug("Default pseudo user = %s\n", puser->pw_name);
303     }
304
305     while (numAcceptable)
306     {
307         if (DisplayTypeMatch (*acceptableTypes, displayType))
308             break;
309         --numAcceptable;
310         ++acceptableTypes;
311     }
312     if (!numAcceptable)
313     {
314         LogError(ReadCatalog(
315                 MC_LOG_SET,MC_LOG_BAD_DPYTYPE,MC_DEF_LOG_BAD_DPYTYPE),
316                   type, name);
317     }
318
319
320     /*
321      *  see if this display is already being managed...
322      */
323
324     d = FindDisplayByName (name);
325     if (d)
326     {
327         d->state = OldEntry;
328         if (class && strcmp (d->class, class))
329         {
330             char    *newclass;
331
332             newclass = malloc ((unsigned) (strlen (class) + 1));
333             if (newclass)
334             {
335                 free (d->class);
336                 strcpy (newclass, class);
337                 d->class = newclass;
338             }
339         }
340         Debug ("Found existing display:  %s %s %s", d->name, d->class ? d->class : "", type);
341         freeArgs (d->argv);
342     }
343     else
344     {
345         d = NewDisplay (name, class);
346         Debug ("Found new display:  %s %s %s", d->name, d->class ? d->class : "", type);
347     }
348     d->displayType = displayType;
349     d->argv = copyArgs (argv);
350     for (a = d->argv; a && *a; a++)
351         Debug (" %s", *a);
352     Debug ("\n");
353
354     /*
355      * add device to display information...
356      */
357      
358     if ( device != NULL && strlen(device) != 0 ) {
359         if (d->gettyLine != NULL)
360             free(d->gettyLine);
361
362         d->gettyLine = strdup(device);
363
364     }
365
366     if (d->gettyLine && 
367         (strcmp(d->gettyLine, "None") == 0 ||
368          strcmp(d->gettyLine, "none") == 0   ) ) {
369
370         strcpy(d->gettyLine,"??");
371     }
372
373
374     freeSomeArgs (args, argv - args);
375 }
376
377 static struct displayMatch {
378         char            *name;
379         DisplayType     type;
380 } displayTypes[] = {
381         "local",                { Local, Permanent, FromFile },
382         "local_uid",            { Local, Permanent, FromFile },
383         "foreign",              { Foreign, Permanent, FromFile },
384         0,                      { Local, Permanent, FromFile },
385 };
386
387 static DisplayType 
388 parseDisplayType( char *string, int *usedDefaultType, int *parse_uid )
389 {
390         struct displayMatch     *d;
391
392         *parse_uid = 0;
393
394         for (d = displayTypes; d->name; d++) {
395             if (strcmp(d->name, string) == 0)
396             {
397                 if (strcmp(d->name, "local_uid") == 0) {
398                    *parse_uid = 1; 
399                 }
400                 *usedDefaultType = 0;
401                 return d->type;
402             }
403         }
404
405         *usedDefaultType = 1;
406         return d->type;
407 }