Fix warnings on FreeBSD
[oweals/cde.git] / cde / lib / DtSvc / DtUtil2 / FileUtil.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 /*
24  * File:         FileUtil.c $XConsortium: FileUtil.c /main/6 1996/11/01 10:06:23 drk $
25  * Language:     C
26  *
27  * (c) Copyright 1988, Hewlett-Packard Company, all rights reserved.
28  *
29  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
30  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
31  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
32  * (c) Copyright 1993, 1994 Novell, Inc.                                *
33  */
34
35 #include <sys/types.h>          /* stat(2) */
36 #include <sys/stat.h>           /* stat(2) */
37 #include <sys/param.h>          /* MAXPATHLEN */
38 #include <errno.h>              /* errno(2) */
39
40 #ifdef __hpux
41 #include <ndir.h>               /* opendir(), directory(3C) */
42 #else
43 #if defined(sun) || defined(CSRG_BASED)
44 #include <dirent.h>             /* opendir(), directory(3C) */
45 #else
46 #include <sys/dir.h>
47 #endif /* sun || CSRG_BASED */
48 #endif /* __hpux */
49
50 #include <X11/Xlib.h>
51 #include <X11/Intrinsic.h>      /* Xt stuff */
52 #include <X11/StringDefs.h>     /* Cardinal */
53 #include <Dt/DtNlUtils.h>
54 #include <Dt/ActionUtilP.h>
55 #include <Tt/tt_c.h>
56
57 /******************
58  *
59  * Function Name:  _DtCreateDirs
60  *
61  * Description:
62  *
63  *      This function is passed a directory path to create and the mode
64  *      for the directory.  It will create any of the parent directories 
65  *      on the path that do not already exist.
66  *
67  *      This function may fail if any of the directories on the path already
68  *      exist and are not writable.  If some component of the path already
69  *      exists and is not a directory, a failure will be returned.  
70  *
71  *      If some component of the path exists as a directory but does not have 
72  *      the specified mode, this will NOT cause a failure to be returned.
73  *      This implies that if this function is called to create a writeable
74  *      directory, it is possible for the function to return successfully
75  *      but the directory may not actually be writable.
76  *
77  * Synopsis:
78  *
79  *      status = _DtCreateDirs (path, mode);
80  *
81  *      int status;             Returns 0 on success and -1 on failure.
82  *      char *path;             The directory path to create.
83  *      int mode;               The file mode for setting any directories
84  *                              that are created.
85  *
86  ******************/
87
88 int 
89 _DtCreateDirs(
90         char *path,
91         int mode )
92 {
93    struct stat st_buf;
94    int st_status;
95    int ret_status;
96    char *parent_path;
97    char *temp_s;
98
99    /* If the path already exist, make sure it is a directory. */
100    if ((st_status = stat (path, &st_buf)) == 0) {
101       if (S_ISDIR (st_buf.st_mode))
102          ret_status = 0;
103       else
104          ret_status = -1;
105    }
106
107    /* If we can't stat it, make sure it is simply because some component
108       of the path doesn't exist. */
109    else if (errno != ENOENT)
110       ret_status = -1;
111
112    else {
113       /* Some component of the path doesn't exist.  Recursively make the
114          parent of the current directory, then make the current directory. */
115       parent_path = XtNewString (path);
116       if ((temp_s = DtStrrchr (parent_path, '/')) != NULL) {
117          *temp_s = '\0';
118          (void) _DtCreateDirs (parent_path, mode);
119       }
120       XtFree (parent_path);
121
122       /* If no error has been encountered, now make the final directory
123          in the path. */
124       if ((ret_status = mkdir (path, S_IFDIR)) == 0)
125             (void) chmod (path, mode);
126    }
127
128    return (ret_status);
129 }
130
131 /******************
132  *
133  * Function Name:  _DtIsOpenableDirContext
134  *
135  * Description:
136  *
137  *      This function takes a path as an argument and determines whether
138  *      the path is a directory that can be opened.  This function returns
139  *      "1" if the path is an openable directory and "0" if it is not.
140  *      In addition, if the calling function passes in another pointer,
141  *      we will return the internal representation for the path.
142  *
143  *      The path can be in the Softbench "context" form of "host:/path/dir".
144  *
145  * Synopsis:
146  *
147  *      status = _DtIsOpenableDirContext (cpath, ret_ptr)
148  *
149  *      int status;             Returns 1 for openable directories, 
150  *                              0 otherwise.
151  *      char *cpath;            The directory name to test.
152  *      char ** ret_ptr;        Where to place internal format.
153  *
154  ******************/
155
156 int 
157 _DtIsOpenableDirContext(
158         char *path,
159         char **ret_path )
160 {
161    char *real_path = NULL;
162    char * tmp_real_path;
163    DIR *dirp;
164    int ret_status;
165    Tt_status status;
166    char * host;
167    char * filename;
168    char * netfile;
169
170    if (ret_path)
171       *ret_path = NULL;
172
173    host = _DtHostString(path);
174    filename = _DtPathname(path);
175    if (host)
176    {
177       netfile = tt_host_file_netfile(host, filename);
178       if ((status = tt_ptr_error(netfile)) == TT_OK)
179       {
180          tmp_real_path = tt_netfile_file(netfile);
181          status = tt_ptr_error(real_path);
182          tt_free(netfile);
183       }
184
185       if (status != TT_OK) {
186          real_path = NULL;
187       } else {
188          real_path = XtNewString(tmp_real_path);
189          tt_free(tmp_real_path);
190       }
191
192       XtFree(filename);
193       XtFree(host);
194    }
195    else
196       real_path = filename;
197
198    if (real_path && ((dirp = opendir (real_path)) != NULL)) 
199    {
200       closedir (dirp);
201       ret_status = 1;
202       if (ret_path)
203          *ret_path = real_path;
204    }
205    else
206    {
207       ret_status = 0;
208       if (real_path)
209          XtFree(real_path);
210    }
211
212    return (ret_status);
213 }
214
215 /******************
216  *
217  * Function Name:  _DtIsOpenableDir
218  *
219  * Description:
220  *
221  *      This function takes a path as an argument and determines whether
222  *      the path is a directory that can be opened.  This function returns
223  *      "1" if the path is an openable directory and "0" if it is not.
224  *
225  *      The path can be in the Softbench "context" form of "host:/path/dir".
226  *
227  * Synopsis:
228  *
229  *      status = _DtIsOpenableDir (cpath)
230  *
231  *      int status;             Returns 1 for openable directories, 
232  *                              0 otherwise.
233  *      char *cpath;            The directory name to test.
234  *
235  ******************/
236
237 int 
238 _DtIsOpenableDir(
239         char *path )
240 {
241    return (_DtIsOpenableDirContext(path, NULL));
242 }