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