suricata
util-path.c
Go to the documentation of this file.
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 "util-debug.h"
28 #include "util-path.h"
29 
30 #ifdef OS_WIN32
31 #define DIRECTORY_SEPARATOR '\\'
32 #else
33 #define DIRECTORY_SEPARATOR '/'
34 #endif
35 
36 /**
37  * \brief Check if a path is absolute
38  *
39  * \param path string with the path
40  *
41  * \retval 1 absolute
42  * \retval 0 not absolute
43  */
44 int PathIsAbsolute(const char *path)
45 {
46  if (strlen(path) > 1 && path[0] == '/') {
47  return 1;
48  }
49 
50 #if (defined OS_WIN32 || defined __CYGWIN__)
51  if (strlen(path) > 2) {
52  if (isalpha((unsigned char)path[0]) && path[1] == ':') {
53  return 1;
54  }
55  }
56 #endif
57 
58  return 0;
59 }
60 
61 /**
62  * \brief Check if a path is relative
63  *
64  * \param path string with the path
65  *
66  * \retval 1 relative
67  * \retval 0 not relative
68  */
69 int PathIsRelative(const char *path)
70 {
71  return PathIsAbsolute(path) ? 0 : 1;
72 }
73 
74 /**
75  * \brief Wrapper to join a directory and filename and resolve using realpath
76  * _fullpath is used for WIN32
77  *
78  * \param out_buf output buffer. Up to PATH_MAX will be written. Unchanged on exit failure.
79  * \param buf_len length of output buffer
80  * \param dir the directory
81  * \param fname the filename
82  *
83  * \retval TM_ECODE_OK on success
84  * \retval TM_ECODE_FAILED on failure
85  */
86 TmEcode PathJoin (char *out_buf, uint16_t buf_len, const char *const dir, const char *const fname)
87 {
88  SCEnter();
89  uint16_t max_path_len = MAX(buf_len, PATH_MAX);
90  int bytes_written = snprintf(out_buf, max_path_len, "%s%c%s", dir, DIRECTORY_SEPARATOR, fname);
91  if (bytes_written <= 0) {
92  SCLogError("Could not join filename to path");
94  }
95  char *tmp_buf = SCRealPath(out_buf, NULL);
96  if (tmp_buf == NULL) {
97  SCLogError("Error resolving path: %s", strerror(errno));
99  }
100  memset(out_buf, 0, buf_len);
101  strlcpy(out_buf, tmp_buf, max_path_len);
102  free(tmp_buf);
104 }
105 
106 /**
107  * \brief Wrapper around SCMkDir with default mode arguments.
108  */
109 int SCDefaultMkDir(const char *path)
110 {
111  return SCMkDir(path, S_IRWXU | S_IRGRP | S_IXGRP);
112 }
113 
114 /**
115  * \brief Recursively create a directory.
116  *
117  * \param path Path to create
118  * \param final true will create the final path component, false will not
119  *
120  * \retval 0 on success
121  * \retval -1 on error
122  */
123 int SCCreateDirectoryTree(const char *path, const bool final)
124 {
125  char pathbuf[PATH_MAX];
126  char *p;
127  size_t len = strlen(path);
128 
129  if (len > PATH_MAX - 1) {
130  return -1;
131  }
132 
133  strlcpy(pathbuf, path, sizeof(pathbuf));
134 
135  for (p = pathbuf + 1; *p; p++) {
136  if (*p == '/') {
137  /* Truncate, while creating directory */
138  *p = '\0';
139 
140  if (SCDefaultMkDir(pathbuf) != 0) {
141  if (errno != EEXIST) {
142  return -1;
143  }
144  }
145 
146  *p = '/';
147  }
148  }
149 
150  if (final) {
151  if (SCDefaultMkDir(pathbuf) != 0) {
152  if (errno != EEXIST) {
153  return -1;
154  }
155  }
156  }
157 
158  return 0;
159 }
160 
161 /**
162  * \brief Check if a path exists.
163  *
164  * \param Path to check for existence
165  *
166  * \retval true if path exists
167  * \retval false if path does not exist
168  */
169 bool SCPathExists(const char *path)
170 {
171  struct stat sb;
172  if (stat(path, &sb) == 0) {
173  return true;
174  }
175  return false;
176 }
177 
178 /**
179  * \brief OS independent wrapper for directory check
180  *
181  * \param dir_entry object to check
182  *
183  * \retval True if the object is a regular directory, otherwise false. This directory
184  * and parent directory will return false.
185  */
186 bool SCIsRegularDirectory(const struct dirent *const dir_entry)
187 {
188 #ifndef OS_WIN32
189  if ((dir_entry->d_type == DT_DIR) &&
190  (strcmp(dir_entry->d_name, ".") != 0) &&
191  (strcmp(dir_entry->d_name, "..") != 0)) {
192  return true;
193  }
194 #endif
195  return false;
196 }
197 /**
198  * \brief OS independent to check for regular file
199  *
200  * \param dir_entry object to check
201  *
202  * \retval True if the object is a regular file. Otherwise false.
203  */
204 bool SCIsRegularFile(const struct dirent *const dir_entry)
205 {
206 #ifndef OS_WIN32
207  return dir_entry->d_type == DT_REG;
208 #endif
209  return false;
210 }
211 
212 /**
213  * \brief OS independent wrapper for realpath
214  *
215  * \param path the path to resolve
216  * \param resolved_path the resolved path; if null, a buffer will be allocated
217  *
218  * \retval the resolved_path; or a pointer to a new resolved_path buffer
219  */
220 char *SCRealPath(const char *path, char *resolved_path)
221 {
222 #ifdef OS_WIN32
223  return _fullpath(resolved_path, path, PATH_MAX);
224 #else
225  return realpath(path, resolved_path);
226 #endif
227 }
228 
229 /*
230  * \brief Return the basename of the provided path.
231  * \param path The path on which to compute the basename
232  *
233  * \retval the basename of the path or NULL if the path lacks a non-leaf
234  */
235 const char *SCBasename(const char *path)
236 {
237  if (!path || strlen(path) == 0)
238  return NULL;
239 
240  char *final = strrchr(path, DIRECTORY_SEPARATOR);
241  if (!final)
242  return path;
243 
244  if (*(final + 1) == '\0')
245  return NULL;
246 
247  return final + 1;
248 }
len
uint8_t len
Definition: app-layer-dnp3.h:2
MAX
#define MAX(x, y)
Definition: suricata-common.h:384
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
SCDefaultMkDir
int SCDefaultMkDir(const char *path)
Wrapper around SCMkDir with default mode arguments.
Definition: util-path.c:109
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
util-debug.h
SCIsRegularDirectory
bool SCIsRegularDirectory(const struct dirent *const dir_entry)
OS independent wrapper for directory check.
Definition: util-path.c:186
DIRECTORY_SEPARATOR
#define DIRECTORY_SEPARATOR
Definition: util-path.c:33
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
TmEcode
TmEcode
Definition: tm-threads-common.h:83
SCBasename
const char * SCBasename(const char *path)
Definition: util-path.c:235
SCPathExists
bool SCPathExists(const char *path)
Check if a path exists.
Definition: util-path.c:169
suricata-common.h
util-path.h
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:44
SCMkDir
#define SCMkDir(a, b)
Definition: util-path.h:29
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCRealPath
char * SCRealPath(const char *path, char *resolved_path)
OS independent wrapper for realpath.
Definition: util-path.c:220
PathIsRelative
int PathIsRelative(const char *path)
Check if a path is relative.
Definition: util-path.c:69
suricata.h
SCIsRegularFile
bool SCIsRegularFile(const struct dirent *const dir_entry)
OS independent to check for regular file.
Definition: util-path.c:204
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
PathJoin
TmEcode PathJoin(char *out_buf, uint16_t buf_len, const char *const dir, const char *const fname)
Wrapper to join a directory and filename and resolve using realpath _fullpath is used for WIN32.
Definition: util-path.c:86
SCCreateDirectoryTree
int SCCreateDirectoryTree(const char *path, const bool final)
Recursively create a directory.
Definition: util-path.c:123