]> git.ipfire.org Git - people/ms/suricata.git/blob - src/util-path.c
core: Remove unneeded consts
[people/ms/suricata.git] / src / util-path.c
1 /* Copyright (C) 2007-2012 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18 /**
19 * \file
20 *
21 * \author Victor Julien <victor@inliniac.net>
22 *
23 */
24
25 #include "suricata-common.h"
26 #include "suricata.h"
27 #include "debug.h"
28 #include "util-debug.h"
29 #include "util-path.h"
30
31 #ifdef OS_WIN32
32 #define DIRECTORY_SEPARATOR '\\'
33 #else
34 #define DIRECTORY_SEPARATOR '/'
35 #endif
36
37 /**
38 * \brief Check if a path is absolute
39 *
40 * \param path string with the path
41 *
42 * \retval 1 absolute
43 * \retval 0 not absolute
44 */
45 int PathIsAbsolute(const char *path)
46 {
47 if (strlen(path) > 1 && path[0] == '/') {
48 return 1;
49 }
50
51 #if (defined OS_WIN32 || defined __CYGWIN__)
52 if (strlen(path) > 2) {
53 if (isalpha((unsigned char)path[0]) && path[1] == ':') {
54 return 1;
55 }
56 }
57 #endif
58
59 return 0;
60 }
61
62 /**
63 * \brief Check if a path is relative
64 *
65 * \param path string with the path
66 *
67 * \retval 1 relative
68 * \retval 0 not relative
69 */
70 int PathIsRelative(const char *path)
71 {
72 return PathIsAbsolute(path) ? 0 : 1;
73 }
74
75 /**
76 * \brief Wrapper to join a directory and filename and resolve using realpath
77 * _fullpath is used for WIN32
78 *
79 * \param out_buf output buffer. Up to PATH_MAX will be written. Unchanged on exit failure.
80 * \param buf_len length of output buffer
81 * \param dir the directory
82 * \param fname the filename
83 *
84 * \retval TM_ECODE_OK on success
85 * \retval TM_ECODE_FAILED on failure
86 */
87 TmEcode PathJoin (char *out_buf, uint16_t buf_len, const char *const dir, const char *const fname)
88 {
89 SCEnter();
90 uint16_t max_path_len = MAX(buf_len, PATH_MAX);
91 int bytes_written = snprintf(out_buf, max_path_len, "%s%c%s", dir, DIRECTORY_SEPARATOR, fname);
92 if (bytes_written <= 0) {
93 SCLogError(SC_ERR_SPRINTF, "Could not join filename to path");
94 SCReturnInt(TM_ECODE_FAILED);
95 }
96 char *tmp_buf = SCRealPath(out_buf, NULL);
97 if (tmp_buf == NULL) {
98 SCLogError(SC_ERR_SPRINTF, "Error resolving path: %s", strerror(errno));
99 SCReturnInt(TM_ECODE_FAILED);
100 }
101 memset(out_buf, 0, buf_len);
102 strlcpy(out_buf, tmp_buf, max_path_len);
103 free(tmp_buf);
104 SCReturnInt(TM_ECODE_OK);
105 }
106
107 /**
108 * \brief Wrapper around SCMkDir with default mode arguments.
109 */
110 int SCDefaultMkDir(const char *path)
111 {
112 return SCMkDir(path, S_IRWXU | S_IRGRP | S_IXGRP);
113 }
114
115 /**
116 * \brief Recursively create a directory.
117 *
118 * \param path Path to create
119 * \param final true will create the final path component, false will not
120 *
121 * \retval 0 on success
122 * \retval -1 on error
123 */
124 int SCCreateDirectoryTree(const char *path, const bool final)
125 {
126 char pathbuf[PATH_MAX];
127 char *p;
128 size_t len = strlen(path);
129
130 if (len > PATH_MAX - 1) {
131 return -1;
132 }
133
134 strlcpy(pathbuf, path, sizeof(pathbuf));
135
136 for (p = pathbuf + 1; *p; p++) {
137 if (*p == '/') {
138 /* Truncate, while creating directory */
139 *p = '\0';
140
141 if (SCDefaultMkDir(pathbuf) != 0) {
142 if (errno != EEXIST) {
143 return -1;
144 }
145 }
146
147 *p = '/';
148 }
149 }
150
151 if (final) {
152 if (SCDefaultMkDir(pathbuf) != 0) {
153 if (errno != EEXIST) {
154 return -1;
155 }
156 }
157 }
158
159 return 0;
160 }
161
162 /**
163 * \brief Check if a path exists.
164 *
165 * \param Path to check for existence
166 *
167 * \retval true if path exists
168 * \retval false if path does not exist
169 */
170 bool SCPathExists(const char *path)
171 {
172 struct stat sb;
173 if (stat(path, &sb) == 0) {
174 return true;
175 }
176 return false;
177 }
178
179 /**
180 * \brief OS independent wrapper for directory check
181 *
182 * \param dir_entry object to check
183 *
184 * \retval True if the object is a regular directory, otherwise false. This directory
185 * and parent directory will return false.
186 */
187 bool SCIsRegularDirectory(const struct dirent *const dir_entry)
188 {
189 #ifndef OS_WIN32
190 if ((dir_entry->d_type == DT_DIR) &&
191 (strcmp(dir_entry->d_name, ".") != 0) &&
192 (strcmp(dir_entry->d_name, "..") != 0)) {
193 return true;
194 }
195 #endif
196 return false;
197 }
198 /**
199 * \brief OS independent to check for regular file
200 *
201 * \param dir_entry object to check
202 *
203 * \retval True if the object is a regular file. Otherwise false.
204 */
205 bool SCIsRegularFile(const struct dirent *const dir_entry)
206 {
207 #ifndef OS_WIN32
208 return dir_entry->d_type == DT_REG;
209 #endif
210 return false;
211 }
212
213 /**
214 * \brief OS independent wrapper for realpath
215 *
216 * \param path the path to resolve
217 * \param resolved_path the resolved path; if null, a buffer will be allocated
218 *
219 * \retval the resolved_path; or a pointer to a new resolved_path buffer
220 */
221 char *SCRealPath(const char *path, char *resolved_path)
222 {
223 #ifdef OS_WIN32
224 return _fullpath(resolved_path, path, PATH_MAX);
225 #else
226 return realpath(path, resolved_path);
227 #endif
228 }
229
230 /*
231 * \brief Return the basename of the provided path.
232 * \param path The path on which to compute the basename
233 *
234 * \retval the basename of the path or NULL if the path lacks a non-leaf
235 */
236 const char *SCBasename(const char *path)
237 {
238 if (!path || strlen(path) == 0)
239 return NULL;
240
241 char *final = strrchr(path, DIRECTORY_SEPARATOR);
242 if (!final)
243 return path;
244
245 if (*(final + 1) == '\0')
246 return NULL;
247
248 return final + 1;
249 }