389 lines
9.9 KiB
C
389 lines
9.9 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
|
|
*/
|
|
/* $TOG: SmCreateDirs.c /main/9 1997/02/24 09:23:16 barstow $ */
|
|
/* *
|
|
* (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. *
|
|
*/
|
|
/******************************************************************************
|
|
*
|
|
* File Name: SmCreateDirs.c
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
#include <stdlib.h>
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xlibint.h>
|
|
#include <X11/Intrinsic.h>
|
|
#include <Dt/DtNlUtils.h>
|
|
#include <Dt/DtPStrings.h>
|
|
#include <Dt/WsmP.h>
|
|
|
|
/******** Private Function Declarations ********/
|
|
|
|
static int
|
|
GetShortHostname (
|
|
char*,
|
|
unsigned int);
|
|
|
|
static char *
|
|
GetSessionDirProperty (
|
|
Display *display);
|
|
|
|
static char *
|
|
GetDisplayName (
|
|
Display *display);
|
|
|
|
|
|
/*************************************<->*************************************
|
|
*
|
|
* _DtCreateDtDirs (display)
|
|
*
|
|
* 1. Creates ~/.dt, ~/.dt/types, ~/.dt/tmp and either
|
|
* ~/.dt/sessions or ~/.dt/<display_name>
|
|
*
|
|
* 2. Returns the name of the session directory
|
|
*
|
|
* Outputs:
|
|
* -------
|
|
* Returns the session directory or NULL if malloc fails or ~/.dt
|
|
* cannot be created
|
|
*
|
|
*************************************<->***********************************/
|
|
|
|
char *
|
|
_DtCreateDtDirs(
|
|
Display *display )
|
|
{
|
|
char *tmpPath;
|
|
Boolean needSessionsDir = False;
|
|
Boolean useOldSession = False;
|
|
struct stat buf;
|
|
int status;
|
|
char *home;
|
|
char *sessionDir;
|
|
char *displayName;
|
|
|
|
/*
|
|
* Sanity check - make sure there's an existing display
|
|
*/
|
|
if(!display)
|
|
return(NULL);
|
|
|
|
if ((home =getenv("HOME")) == NULL)
|
|
home = "";
|
|
|
|
tmpPath = (char *) XtMalloc((MAXPATHLEN + 1) * sizeof(char));
|
|
if(tmpPath == NULL)
|
|
return(NULL);
|
|
|
|
/*
|
|
* If the $HOME/.dt directory does not exist, create it
|
|
*/
|
|
strcpy(tmpPath, home);
|
|
strcat(tmpPath, "/" DtPERSONAL_CONFIG_DIRECTORY);
|
|
|
|
status = stat(tmpPath, &buf);
|
|
if (status == -1) {
|
|
status = mkdir(tmpPath, 0000);
|
|
if (status == -1) {
|
|
XtFree(tmpPath);
|
|
return(NULL);
|
|
}
|
|
(void)chmod(tmpPath, 0755);
|
|
}
|
|
|
|
/*
|
|
* Create the personal DB directory if it does not exist.
|
|
*/
|
|
strcpy(tmpPath, home);
|
|
strcat(tmpPath, "/" DtPERSONAL_DB_DIRECTORY);
|
|
|
|
if ((status = stat (tmpPath, &buf)) == -1) {
|
|
if ((status = mkdir (tmpPath, 0000)) != -1)
|
|
(void) chmod (tmpPath, 0755);
|
|
}
|
|
|
|
/*
|
|
* Create the personal tmp dir if it does not exist.
|
|
*/
|
|
strcpy(tmpPath, home);
|
|
strcat(tmpPath, "/" DtPERSONAL_TMP_DIRECTORY);
|
|
|
|
if ((status = stat (tmpPath, &buf)) == -1) {
|
|
if ((status = mkdir (tmpPath, 0000)) != -1)
|
|
(void) chmod (tmpPath, 0755);
|
|
}
|
|
|
|
/*
|
|
* The creation of the session directory is tricky:
|
|
*
|
|
* For CDE 1.0 sessions, if a display-specific directory exists,
|
|
* it will take precedence. CDE 1.0 does not support the selection
|
|
* of a session.
|
|
*
|
|
* However, for newer CDE implementations, if a specific session
|
|
* was selected, the specified session will be used. If no session
|
|
* was selected, the CDE 1.0 mechanism will be used.
|
|
*
|
|
* If a CDEnext session is being used, the session directory will
|
|
* be on a property on the root window.
|
|
*
|
|
* Must check for this property and use it if is set.
|
|
*/
|
|
if ((sessionDir = GetSessionDirProperty (display)) != NULL) {
|
|
if (!strcmp (sessionDir, DtSM_SESSION_DIRECTORY)) {
|
|
/*
|
|
* Need to create a DtSM_SESSION_DIRECTORY dir if it
|
|
* does not exist.
|
|
*/
|
|
needSessionsDir = True;
|
|
|
|
} else if (!strcmp (sessionDir, DtSM_SESSION_DISPLAY_DIRECTORY)) {
|
|
/*
|
|
* Create a directory for a display-specific session if necessary
|
|
*/
|
|
if ((displayName = GetDisplayName (display)) != NULL) {
|
|
|
|
strcpy (tmpPath, home);
|
|
strcat (tmpPath, "/" DtPERSONAL_CONFIG_DIRECTORY);
|
|
strcat (tmpPath, "/");
|
|
strcat (tmpPath, displayName);
|
|
|
|
free(displayName); /* CDExc22771 */
|
|
|
|
if ((status = stat (tmpPath, &buf)) == -1) {
|
|
if ((status = mkdir (tmpPath, 0000)) != -1)
|
|
(void) chmod (tmpPath, 0755);
|
|
else
|
|
useOldSession = True;
|
|
}
|
|
}
|
|
else {
|
|
/*
|
|
* Something's wrong with the display, use the fallback
|
|
*/
|
|
useOldSession = True;
|
|
}
|
|
} else {
|
|
/*
|
|
* The property contains an unrecognized value, fallback to
|
|
* other session selection algorithm.
|
|
*/
|
|
useOldSession = True;
|
|
}
|
|
XFree (sessionDir);
|
|
}
|
|
else
|
|
useOldSession = True;
|
|
|
|
if (useOldSession) {
|
|
/*
|
|
* Check for a display dependent directory. If one exists,
|
|
* it will be used.
|
|
*
|
|
* This is done for backward compatibility - THE DISPLAY
|
|
* DEPENDENT DIR TAKES PRECEDENT.
|
|
*/
|
|
if ((displayName = GetDisplayName (display)) != NULL) {
|
|
|
|
strcpy (tmpPath, home);
|
|
strcat (tmpPath, "/" DtPERSONAL_CONFIG_DIRECTORY);
|
|
strcat (tmpPath, "/");
|
|
strcat (tmpPath, displayName);
|
|
|
|
free(displayName); /* CDExc22771 */
|
|
|
|
if ((status = stat(tmpPath, &buf)) != 0)
|
|
/*
|
|
* The display directory does not exist
|
|
*/
|
|
needSessionsDir = True;
|
|
}
|
|
else
|
|
needSessionsDir = True;
|
|
}
|
|
|
|
if(needSessionsDir)
|
|
{
|
|
/*
|
|
* If we don't have an old style directory - we check for a sessions
|
|
* directory, and create it if it doesn't exist
|
|
*/
|
|
strcpy (tmpPath, home);
|
|
strcat (tmpPath, "/" DtPERSONAL_CONFIG_DIRECTORY);
|
|
strcat (tmpPath, "/" DtSM_SESSION_DIRECTORY);
|
|
|
|
if ((status = stat(tmpPath, &buf)) == -1) {
|
|
if ((status = mkdir(tmpPath, 0000)) == -1) {
|
|
XtFree(tmpPath);
|
|
return(NULL);
|
|
}
|
|
(void)chmod(tmpPath, 0755);
|
|
}
|
|
}
|
|
|
|
return(tmpPath);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------+*/
|
|
|
|
static int
|
|
GetShortHostname(
|
|
char *buffer,
|
|
unsigned int bufsize )
|
|
{
|
|
char * ptr;
|
|
int status;
|
|
|
|
if (status = gethostname(buffer, bufsize))
|
|
return status; /* failed gethostname */
|
|
if (ptr = strstr(buffer, (char *)"."))
|
|
*ptr = '\0'; /* delete domain name if there is one */
|
|
return 0;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------+*/
|
|
|
|
/*
|
|
* GetSessionDirProperty -
|
|
*/
|
|
static char *
|
|
GetSessionDirProperty (
|
|
Display *display)
|
|
{
|
|
int propStatus;
|
|
Atom actualType;
|
|
int actualFormat;
|
|
unsigned long nitems;
|
|
unsigned long leftover;
|
|
char *property = NULL;
|
|
Atom tmpAtom;
|
|
|
|
tmpAtom = XInternAtom(display, _XA_DT_RESTORE_DIR, False);
|
|
|
|
propStatus = XGetWindowProperty (display, RootWindow(display, 0),
|
|
(Atom) tmpAtom, 0L,
|
|
1000000L, False,
|
|
AnyPropertyType, &actualType,
|
|
&actualFormat, &nitems, &leftover,
|
|
(unsigned char **)&property);
|
|
|
|
if (propStatus == Success && actualType != None &&
|
|
actualFormat == 8 && nitems != 0)
|
|
return(property);
|
|
|
|
if (property)
|
|
XFree(property);
|
|
return (NULL);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------+*/
|
|
|
|
/*
|
|
* GetDisplayName -
|
|
*/
|
|
static char *
|
|
GetDisplayName (
|
|
Display *display)
|
|
{
|
|
char *tmpPath;
|
|
char hostName[101], displayName[101];
|
|
char *pch, *tmpNumber = NULL;
|
|
char *returnPath;
|
|
|
|
/*
|
|
* Create the display name and append it to the current path.
|
|
*/
|
|
(void)strcpy(hostName, display->display_name);
|
|
(void)strcpy(displayName, display->display_name);
|
|
|
|
/*
|
|
* If this is run to unix or local get the host name - otherwise
|
|
* just use what we have
|
|
*/
|
|
|
|
/*
|
|
* Strip host name to nothing but the unqualified (short) host name
|
|
*/
|
|
if (pch = DtStrchr(hostName, ':'))
|
|
*pch = '\0';
|
|
|
|
if (pch = DtStrchr(hostName, '.'))
|
|
*pch = '\0';
|
|
|
|
if((!strcmp(hostName, "unix")) || (!strcmp(hostName, "local"))
|
|
|| (!strcmp(hostName, "")))
|
|
{
|
|
/*
|
|
* host name is local - get the real name
|
|
*/
|
|
(void) GetShortHostname(hostName, 25);
|
|
}
|
|
|
|
/*
|
|
* Strip screen off of display name
|
|
*/
|
|
if (tmpNumber = DtStrchr(displayName, ':'))
|
|
if (pch = DtStrchr(tmpNumber, '.'))
|
|
*pch = '\0';
|
|
|
|
/*
|
|
* Strip it down to 14 chars (actually, 14 bytes or less)
|
|
*/
|
|
if((strlen(tmpNumber) + strlen(hostName)) > (size_t)14)
|
|
{
|
|
size_t tnLen;
|
|
int lastChLen;
|
|
char *lastCh;
|
|
|
|
/* Pare display number to at most 12 bytes */
|
|
while ((tnLen = strlen(tmpNumber)) > (size_t)12)
|
|
{
|
|
/* Remove the last character, an try again */
|
|
DtLastChar(tmpNumber, &lastCh, &lastChLen);
|
|
*lastCh = '\0';
|
|
}
|
|
|
|
/* Pare down host name, if necessary */
|
|
while ((strlen(hostName) + tnLen) > (size_t)14)
|
|
{
|
|
/* Remove the last character, and try again */
|
|
DtLastChar(hostName, &lastCh, &lastChLen);
|
|
*lastCh = '\0';
|
|
}
|
|
}
|
|
|
|
strcat (hostName, tmpNumber);
|
|
|
|
returnPath = strdup (hostName);
|
|
|
|
return (returnPath);
|
|
}
|