XlationSvc: remove a "'" added in previous spelling commit that causes warnings
[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;
87     Boolean             needSessionsDir = False;
88     Boolean             useOldSession = False;
89     struct stat         buf;
90     int                 status;
91     char                *home;
92     char                *sessionDir;
93     char                *displayName;
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 + 1);
105     if(tmpPath == NULL)
106         return(NULL);
107
108     /*
109      * If the $HOME/.dt directory does not exist, create it
110      */
111     strncpy(tmpPath, home, MAXPATHLEN);
112     strncat(tmpPath, "/" DtPERSONAL_CONFIG_DIRECTORY, MAXPATHLEN);
113
114     status = stat(tmpPath, &buf);
115     if (status == -1) {
116         status = mkdir(tmpPath, 0000);
117         if (status == -1) {
118             XtFree(tmpPath);
119             return(NULL);
120         }
121         (void)chmod(tmpPath, 0755);
122     }
123
124     /*
125      * Create the personal DB directory if it does not exist.  
126      */
127     strncpy(tmpPath, home, MAXPATHLEN);
128     strncat(tmpPath, "/" DtPERSONAL_DB_DIRECTORY, MAXPATHLEN);
129     
130     if ((status = stat (tmpPath, &buf)) == -1) {
131         if ((status = mkdir (tmpPath, 0000)) != -1)
132             (void) chmod (tmpPath, 0755);
133     }
134
135     /*
136      * Create the personal tmp dir if it does not exist.
137      */
138     strncpy(tmpPath, home, MAXPATHLEN);
139     strncat(tmpPath, "/" DtPERSONAL_TMP_DIRECTORY, MAXPATHLEN);
140
141     if ((status = stat (tmpPath, &buf)) == -1) {
142         if ((status = mkdir (tmpPath, 0000)) != -1)
143             (void) chmod (tmpPath, 0755);
144     }
145
146     /*
147      * The creation of the session directory is tricky:
148      *  
149      *   For CDE 1.0 sessions, if a display-specific directory exists,
150      *   it will take precedence.  CDE 1.0 does not support the selection
151      *   of a session.
152      *
153      *   However, for newer CDE implementations, if a specific session
154      *   was selected, the specified session will be used.  If no session
155      *   was selected, the CDE 1.0 mechanism will be used.
156      *
157      * If a CDEnext session is being used, the session directory will
158      * be on a property on the root window.  
159      *
160      * Must check for this property and use it if is set.
161      */
162     if ((sessionDir = GetSessionDirProperty (display)) != NULL) {
163         if (!strcmp (sessionDir, DtSM_SESSION_DIRECTORY)) {
164             /*
165              * Need to create a DtSM_SESSION_DIRECTORY dir if it
166              * does not exist.
167              */
168             needSessionsDir = True;
169
170         } else if (!strcmp (sessionDir, DtSM_SESSION_DISPLAY_DIRECTORY)) {
171             /*
172              * Create a directory for a display-specific session if necessary
173              */
174             if ((displayName = GetDisplayName (display)) != NULL) {
175
176                 strncpy (tmpPath, home, MAXPATHLEN);
177                 strncat (tmpPath, "/" DtPERSONAL_CONFIG_DIRECTORY, MAXPATHLEN);
178                 strncat (tmpPath, "/", MAXPATHLEN);
179                 strncat (tmpPath, displayName, MAXPATHLEN);
180
181                 free(displayName);  /* CDExc22771 */
182
183                 if ((status = stat (tmpPath, &buf)) == -1) {
184                     if ((status = mkdir (tmpPath, 0000)) != -1)
185                         (void) chmod (tmpPath, 0755);
186                     else
187                         useOldSession = True;
188                 }
189             }
190             else {
191                 /*
192                  * Something's wrong with the display, use the fallback
193                  */
194                 useOldSession = True; 
195             }
196         } else {
197             /*
198              * The property contains an unrecognized value, fallback to
199              * other session selection algorithm.
200              */
201             useOldSession = True; 
202         }
203         XFree (sessionDir);
204     }
205     else
206         useOldSession = True; 
207     
208     if (useOldSession) {
209         /*
210          *  Check for a display dependent directory.  If one exists, 
211          *  it will be used.
212          *  
213          *  This is done for backward compatibility - THE DISPLAY 
214          *  DEPENDENT DIR TAKES PRECEDENT.
215          */
216         if ((displayName = GetDisplayName (display)) != NULL) {
217
218             strncpy (tmpPath, home, MAXPATHLEN);
219             strncat (tmpPath, "/" DtPERSONAL_CONFIG_DIRECTORY, MAXPATHLEN);
220             strncat (tmpPath, "/", MAXPATHLEN);
221             strncat (tmpPath, displayName, MAXPATHLEN);
222
223             free(displayName);  /* CDExc22771 */
224
225             if ((status = stat(tmpPath, &buf)) != 0)
226                 /*
227                  * The display directory does not exist
228                  */
229                 needSessionsDir = True;
230         }
231         else
232             needSessionsDir = True;
233     }
234
235     if(needSessionsDir)
236     {
237         /*
238          *  If we don't have an old style directory - we check for a sessions
239          *  directory, and create it if it doesn't exist
240          */
241         strncpy (tmpPath, home, MAXPATHLEN);
242         strncat (tmpPath, "/" DtPERSONAL_CONFIG_DIRECTORY, MAXPATHLEN);
243         strncat (tmpPath, "/" DtSM_SESSION_DIRECTORY, MAXPATHLEN);
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 }