cdesktopenv/cde/programs/dtlogin/file.c

410 lines
9.3 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* *
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
* (c) Copyright 1993, 1994 International Business Machines Corp. *
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
* (c) Copyright 1993, 1994 Novell, Inc. *
*/
/*
* xdm - display manager daemon
*
* $XConsortium: file.c /main/4 1995/10/27 16:13:19 rswiston $
*
* Copyright 1988 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of M.I.T. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. M.I.T. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* Author: Keith Packard, MIT X Consortium
*/
/*
* file.c
*/
# include "dm.h"
# include "vgmsg.h"
# include <ctype.h>
# include <signal.h>
# include <pwd.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <netdb.h>
/***************************************************************************
*
* Local procedure declarations
*
***************************************************************************/
static int DisplayTypeMatch( DisplayType d1, DisplayType d2) ;
static void freeArgs( char **args) ;
static void freeSomeArgs( char **args, int n) ;
static DisplayType parseDisplayType( char *string, int *usedDefaultType, int *parse_uid) ;
static char ** splitIntoWords( char *s) ;
static char ** copyArgs( char **args) ;
/***************************************************************************
*
* main
*
***************************************************************************/
static int
DisplayTypeMatch( DisplayType d1, DisplayType d2 )
{
return d1.location == d2.location &&
d1.lifetime == d2.lifetime &&
d1.origin == d2.origin;
}
static void
freeArgs( char **args )
{
char **a;
for (a = args; *a; a++)
free (*a);
free ((char *) args);
}
static char **
splitIntoWords( char *s )
{
char **args, **newargs;
char *wordStart;
int nargs;
args = 0;
nargs = 0;
while (*s)
{
while (*s && isspace (*s))
++s;
if (!*s || *s == '#')
break;
wordStart = s;
while (*s && *s != '#' && !isspace (*s))
++s;
if (!args)
{
args = (char **) malloc (2 * sizeof (char *));
if (!args)
return NULL;
}
else
{
newargs = (char **) realloc ((char *) args,
(nargs+2)*sizeof (char *));
if (!newargs)
{
freeArgs (args);
return NULL;
}
args = newargs;
}
args[nargs] = malloc (s - wordStart + 1);
if (!args[nargs])
{
freeArgs (args);
return NULL;
}
strncpy (args[nargs], wordStart, s - wordStart);
args[nargs][s-wordStart] = '\0';
++nargs;
args[nargs] = NULL;
}
return args;
}
static char **
copyArgs( char **args )
{
char **a, **new, **n;
for (a = args; *a; a++)
;
new = (char **) malloc ((a - args + 1) * sizeof (char *));
if (!new)
return NULL;
n = new;
a = args;
while (*n++ = *a++)
;
return new;
}
static void
freeSomeArgs( char **args, int n )
{
char **a;
a = args;
while (n--)
free (*a++);
free ((char *) args);
}
int
ParseDisplay( char *source,
DisplayType *acceptableTypes,
int numAcceptable,
struct passwd *puser)
{
char **args, **argv, **a;
char *name, *class, *type;
struct display *d;
int usedDefaultType;
int parse_uid;
DisplayType displayType;
char *device=NULL; /* ITE device associated with display */
args = splitIntoWords (source);
if (!args)
return 0;
if (!args[0])
{
LogError(ReadCatalog(MC_LOG_SET,MC_LOG_MISS_NAME,MC_DEF_LOG_MISS_NAME));
freeArgs (args);
return 0;
}
name = args[0];
if (!args[1])
{
LogError(ReadCatalog(MC_LOG_SET,MC_LOG_MISS_TYPE,MC_DEF_LOG_MISS_TYPE),
args[0]);
freeArgs (args);
return 0;
}
/*
* strip off display device if found in second field...
*/
if ( (device = strchr(args[1],'@')) != NULL) {
*device = '\0';
device++;
}
displayType = parseDisplayType (args[1], &usedDefaultType, &parse_uid);
class = NULL;
type = args[1];
argv = args + 2;
/*
* check for special syntax "*" and expand to host name.
* if hostname cannot be found in a database, assume invalid and
* delete.
*/
if ( strcmp(name, "*") == 0) {
char tname[128];
struct hostent *hostent;
strcpy(tname,"");
gethostname(tname, sizeof(tname));
if ( (hostent = gethostbyname(tname)) == NULL ) {
LogError(
ReadCatalog(MC_LOG_SET,MC_LOG_INV_HOSTNM,MC_DEF_LOG_INV_HOSTNM),
tname);
strcpy(tname,"");
}
/*
else
strcpy(tname,hostent->h_name);
*/
strcat(tname, ":0");
name = tname;
}
/*
* extended syntax; if the second argument doesn't
* exactly match a legal display type and the third
* argument does, use the second argument as the
* display class string
*/
if (usedDefaultType && args[2])
{
/*
* strip off display device if found in third field...
*/
if ( device == NULL && (device = strchr(args[2],'@')) != NULL) {
*device = '\0';
device++;
}
displayType = parseDisplayType (args[2], &usedDefaultType, &parse_uid);
if (!usedDefaultType)
{
class = args[1];
type = args[2];
argv = args + 3;
}
}
/*
* extended syntax; if the display type argument was
* "local_uid", then next argument is pseudo user id
* under which the local Xserver is to be run.
*/
if (parse_uid) {
struct passwd *p;
Debug("Xservers 'local_uid' pseudo user = %s\n", *argv);
if ( (p = getpwnam (*argv)) != NULL) {
*puser = *p;
} else {
Debug("Could not get password entry for user name '%s'\n", *argv);
Debug("Using default pseudo user = %s\n", puser->pw_name);
}
argv = argv + 1;
} else {
Debug("Default pseudo user = %s\n", puser->pw_name);
}
while (numAcceptable)
{
if (DisplayTypeMatch (*acceptableTypes, displayType))
break;
--numAcceptable;
++acceptableTypes;
}
if (!numAcceptable)
{
LogError(ReadCatalog(
MC_LOG_SET,MC_LOG_BAD_DPYTYPE,MC_DEF_LOG_BAD_DPYTYPE),
type, name);
}
/*
* see if this display is already being managed...
*/
d = FindDisplayByName (name);
if (d)
{
d->state = OldEntry;
if (class && strcmp (d->class, class))
{
char *newclass;
newclass = malloc ((unsigned) (strlen (class) + 1));
if (newclass)
{
free (d->class);
strcpy (newclass, class);
d->class = newclass;
}
}
Debug ("Found existing display: %s %s %s", d->name, d->class ? d->class : "", type);
freeArgs (d->argv);
}
else
{
d = NewDisplay (name, class);
Debug ("Found new display: %s %s %s", d->name, d->class ? d->class : "", type);
}
d->displayType = displayType;
d->argv = copyArgs (argv);
for (a = d->argv; a && *a; a++)
Debug (" %s", *a);
Debug ("\n");
/*
* add device to display information...
*/
if ( device != NULL && strlen(device) != 0 ) {
if (d->gettyLine != NULL)
free(d->gettyLine);
d->gettyLine = strdup(device);
}
if (d->gettyLine &&
(strcmp(d->gettyLine, "None") == 0 ||
strcmp(d->gettyLine, "none") == 0 ) ) {
strcpy(d->gettyLine,"??");
}
freeSomeArgs (args, argv - args);
return 1;
}
static struct displayMatch {
char *name;
DisplayType type;
} displayTypes[] = {
"local", { Local, Permanent, FromFile },
"local_uid", { Local, Permanent, FromFile },
"foreign", { Foreign, Permanent, FromFile },
0, { Local, Permanent, FromFile },
};
static DisplayType
parseDisplayType( char *string, int *usedDefaultType, int *parse_uid )
{
struct displayMatch *d;
*parse_uid = 0;
for (d = displayTypes; d->name; d++) {
if (strcmp(d->name, string) == 0)
{
if (strcmp(d->name, "local_uid") == 0) {
*parse_uid = 1;
}
*usedDefaultType = 0;
return d->type;
}
}
*usedDefaultType = 1;
return d->type;
}