Convert uses of XKeycodeToKeysym (deprecated) to XkbKeycodeToKeysym
[oweals/cde.git] / cde / lib / DtSvc / DtUtil2 / SmCreateDirs.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 /* $TOG: SmCreateDirs.c /main/9 1997/02/24 09:23:16 barstow $ */
24 /*                                                                            *
25  * (c) Copyright 1993, 1994 Hewlett-Packard Company                           *
26  * (c) Copyright 1993, 1994 International Business Machines Corp.             *
27  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                            *
28  * (c) Copyright 1993, 1994 Novell, Inc.                                      *
29  */
30 /******************************************************************************
31  *
32  * File Name: SmCreateDirs.c
33  *
34  *****************************************************************************/
35
36 #include <stdio.h>
37 #include <sys/param.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <sys/wait.h>
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <X11/Xlib.h>
44 #include <X11/Xlibint.h>
45 #include <X11/Intrinsic.h>
46 #include <Dt/DtNlUtils.h>
47 #include <Dt/DtPStrings.h>
48 #include <Dt/WsmP.h>
49
50 /********    Private Function Declarations    ********/
51
52 static int 
53 GetShortHostname (
54         char*, 
55         unsigned int);
56
57 static char *
58 GetSessionDirProperty (
59         Display         *display);
60
61 static char *
62 GetDisplayName (
63         Display         *display);
64
65
66 /*************************************<->*************************************
67  *
68  *  _DtCreateDtDirs (display) 
69  *
70  *    1. Creates ~/.dt, ~/.dt/types, ~/.dt/tmp and either 
71  *       ~/.dt/sessions or ~/.dt/<display_name>
72  *
73  *    2. Returns the name of the session directory
74  *
75  *  Outputs:
76  *  -------
77  *  Returns the session directory or NULL if malloc fails or ~/.dt
78  *  cannot be created
79  *
80  *************************************<->***********************************/
81
82 char * 
83 _DtCreateDtDirs(
84         Display *display )
85 {
86     char                *tmpPath = NULL;
87     Boolean             needSessionsDir = False;
88     Boolean             useOldSession = False;
89     struct stat         buf;
90     int                 status;
91     char                *home = NULL;
92     char                *sessionDir = NULL;
93     char                *displayName = NULL;
94
95     /*
96      * Sanity check - make sure there's an existing display
97      */
98     if(!display)
99         return(NULL);
100
101     if ((home = getenv("HOME")) == NULL)
102         home = "";
103
104     tmpPath = XtCalloc(1, MAXPATHLEN);
105     if(tmpPath == NULL)
106         return(NULL);
107
108     /*
109      * If the $HOME/.dt directory does not exist, create it
110      */
111     snprintf(tmpPath, MAXPATHLEN, "%s/%s", home, DtPERSONAL_CONFIG_DIRECTORY);
112
113     status = stat(tmpPath, &buf);
114     if (status == -1) {
115         status = mkdir(tmpPath, 0000);
116         if (status == -1) {
117             XtFree(tmpPath);
118             return(NULL);
119         }
120         (void)chmod(tmpPath, 0755);
121     }
122
123     /*
124      * Create the personal DB directory if it does not exist.
125      */
126     snprintf(tmpPath, MAXPATHLEN, "%s/%s", home, DtPERSONAL_DB_DIRECTORY);
127
128     if ((status = stat (tmpPath, &buf)) == -1) {
129         if ((status = mkdir (tmpPath, 0000)) != -1)
130             (void) chmod (tmpPath, 0755);
131     }
132
133     /*
134      * Create the personal tmp dir if it does not exist.
135      */
136     snprintf(tmpPath, MAXPATHLEN, "%s/%s", home, DtPERSONAL_TMP_DIRECTORY);
137
138     if ((status = stat (tmpPath, &buf)) == -1) {
139         if ((status = mkdir (tmpPath, 0000)) != -1)
140             (void) chmod (tmpPath, 0755);
141     }
142
143     /*
144      * The creation of the session directory is tricky:
145      *  
146      *   For CDE 1.0 sessions, if a display-specific directory exists,
147      *   it will take precedence.  CDE 1.0 does not support the selection
148      *   of a session.
149      *
150      *   However, for newer CDE implementations, if a specific session
151      *   was selected, the specified session will be used.  If no session
152      *   was selected, the CDE 1.0 mechanism will be used.
153      *
154      * If a CDEnext session is being used, the session directory will
155      * be on a property on the root window.  
156      *
157      * Must check for this property and use it if is set.
158      */
159     if ((sessionDir = GetSessionDirProperty (display)) != NULL) {
160         if (!strcmp (sessionDir, DtSM_SESSION_DIRECTORY)) {
161             /*
162              * Need to create a DtSM_SESSION_DIRECTORY dir if it
163              * does not exist.
164              */
165             needSessionsDir = True;
166
167         } else if (!strcmp (sessionDir, DtSM_SESSION_DISPLAY_DIRECTORY)) {
168             /*
169              * Create a directory for a display-specific session if necessary
170              */
171             if ((displayName = GetDisplayName (display)) != NULL) {
172
173                 snprintf(tmpPath, MAXPATHLEN, "%s/%s/%s",
174                          home,
175                          DtPERSONAL_CONFIG_DIRECTORY,
176                          displayName);
177
178                 free(displayName);  /* CDExc22771 */
179                 displayName = NULL;
180
181                 if ((status = stat (tmpPath, &buf)) == -1) {
182                     if ((status = mkdir (tmpPath, 0000)) != -1)
183                         (void) chmod (tmpPath, 0755);
184                     else
185                         useOldSession = True;
186                 }
187             }
188             else {
189                 /*
190                  * Something's wrong with the display, use the fallback
191                  */
192                 useOldSession = True; 
193             }
194         } else {
195             /*
196              * The property contains an unrecognized value, fallback to
197              * other session selection algorithm.
198              */
199             useOldSession = True; 
200         }
201         XFree (sessionDir);
202     }
203     else
204         useOldSession = True; 
205     
206     if (useOldSession) {
207         /*
208          *  Check for a display dependent directory.  If one exists, 
209          *  it will be used.
210          *  
211          *  This is done for backward compatibility - THE DISPLAY 
212          *  DEPENDENT DIR TAKES PRECEDENT.
213          */
214         if ((displayName = GetDisplayName (display)) != NULL) {
215
216             snprintf(tmpPath, MAXPATHLEN, "%s/%s/%s",
217                      home,
218                      DtPERSONAL_CONFIG_DIRECTORY,
219                      displayName);
220
221             free(displayName);  /* CDExc22771 */
222             displayName = NULL;
223
224             if ((status = stat(tmpPath, &buf)) != 0)
225                 /*
226                  * The display directory does not exist
227                  */
228                 needSessionsDir = True;
229         }
230         else
231             needSessionsDir = True;
232     }
233
234     if(needSessionsDir)
235     {
236         /*
237          *  If we don't have an old style directory - we check for a sessions
238          *  directory, and create it if it doesn't exist
239          */
240         snprintf(tmpPath, MAXPATHLEN, "%s/%s/%s",
241                  home,
242                  DtPERSONAL_CONFIG_DIRECTORY,
243                  DtSM_SESSION_DIRECTORY);
244
245         if ((status = stat(tmpPath, &buf)) == -1) {
246             if ((status = mkdir(tmpPath, 0000)) == -1) {
247                 XtFree(tmpPath);
248                 return(NULL);
249             }
250             (void)chmod(tmpPath, 0755);
251         }
252     }
253
254     return(tmpPath);
255 }
256
257 /*------------------------------------------------------------------------+*/
258
259 static int
260 GetShortHostname(
261         char *buffer,
262         unsigned int bufsize )
263 {
264    char * ptr;
265    int status;
266
267    if ((status = gethostname(buffer, bufsize)))
268       return status; /* failed gethostname */
269    if ((ptr = strstr(buffer, (char *)".")))
270       *ptr = '\0';  /* delete domain name if there is one */
271    return 0;
272 }
273
274 /*------------------------------------------------------------------------+*/
275
276 /*
277  * GetSessionDirProperty -
278  */
279 static char *
280 GetSessionDirProperty (
281         Display         *display)
282 {
283         int                     propStatus;
284         Atom                    actualType;
285         int                     actualFormat;
286         unsigned long           nitems;
287         unsigned long           leftover;
288         char                    *property = NULL;
289         Atom                    tmpAtom;
290
291         tmpAtom = XInternAtom(display, _XA_DT_RESTORE_DIR, False);
292
293         propStatus = XGetWindowProperty (display, RootWindow(display, 0),
294                                         (Atom) tmpAtom, 0L,
295                                         1000000L, False,
296                                         AnyPropertyType, &actualType,
297                                         &actualFormat, &nitems, &leftover,
298                                         (unsigned char **)&property);
299
300         if (propStatus == Success && actualType != None && 
301                         actualFormat == 8 && nitems != 0)
302                 return(property);
303
304         if (property)
305                 XFree(property);
306         return (NULL);
307 }
308
309 /*------------------------------------------------------------------------+*/
310
311 /*
312  * GetDisplayName -
313  */
314 static char *
315 GetDisplayName (
316         Display         *display)
317 {
318     char                *tmpPath;
319     char                hostName[101], displayName[101];
320     char                *pch, *tmpNumber = NULL;
321     char                *returnPath;
322
323     /*
324      * Create the display name and append it to the current path.
325      */
326     snprintf(hostName, sizeof(hostName), "%s", display->display_name);
327     snprintf(displayName, sizeof(displayName), "%s", display->display_name);
328     
329     /*
330      * If this is run to unix or local get the host name - otherwise
331      * just use what we have
332      */
333
334     /*
335      * Strip host name to nothing but the unqualified (short) host name
336      */
337     if ((pch = DtStrchr(hostName, ':')))
338         *pch = '\0';
339
340     if ((pch = DtStrchr(hostName, '.')))
341         *pch = '\0';
342
343     if((!strcmp(hostName, "unix")) || (!strcmp(hostName, "local"))
344        || (!strcmp(hostName, "")))
345     {
346         /*
347          * host name is local - get the real name
348          */
349         (void) GetShortHostname(hostName, 25);
350     }
351     
352     /*
353      * Strip screen off of display name
354      */
355     if ((tmpNumber = DtStrchr(displayName, ':')))
356         if ((pch = DtStrchr(tmpNumber, '.')))
357             *pch = '\0';
358
359     /*
360      * Strip it down to 14 chars (actually, 14 bytes or less)
361      */
362     if((strlen(tmpNumber) + strlen(hostName)) > (size_t)14)
363     {
364         size_t          tnLen;
365         int             lastChLen;
366         char            *lastCh;
367
368         /* Pare display number to at most 12 bytes */
369         while ((tnLen = strlen(tmpNumber)) > (size_t)12)
370         {
371             /* Remove the last character, an try again */
372             DtLastChar(tmpNumber, &lastCh, &lastChLen);
373             *lastCh = '\0';
374         }
375
376         /* Pare down host name, if necessary */
377         while ((strlen(hostName) + tnLen) > (size_t)14)
378         {
379             /* Remove the last character, and try again */
380             DtLastChar(hostName, &lastCh, &lastChLen);
381             *lastCh = '\0';
382         }
383     }
384     
385     strcat (hostName, tmpNumber);
386
387     returnPath = strdup (hostName);
388
389     return (returnPath);
390 }