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 "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");
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));
100  }
101  memset(out_buf, 0, buf_len);
102  strlcpy(out_buf, tmp_buf, max_path_len);
103  free(tmp_buf);
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 }
len
uint8_t len
Definition: app-layer-dnp3.h:2
MAX
#define MAX(x, y)
Definition: suricata-common.h:381
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
SCDefaultMkDir
int SCDefaultMkDir(const char *path)
Wrapper around SCMkDir with default mode arguments.
Definition: util-path.c:110
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:187
DIRECTORY_SEPARATOR
#define DIRECTORY_SEPARATOR
Definition: util-path.c:34
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
SC_ERR_SPRINTF
@ SC_ERR_SPRINTF
Definition: util-error.h:42
TmEcode
TmEcode
Definition: tm-threads-common.h:79
SCBasename
const char * SCBasename(const char *path)
Definition: util-path.c:236
SCPathExists
bool SCPathExists(const char *path)
Check if a path exists.
Definition: util-path.c:170
suricata-common.h
util-path.h
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:45
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
SCMkDir
#define SCMkDir(a, b)
Definition: util-path.h:29
SCRealPath
char * SCRealPath(const char *path, char *resolved_path)
OS independent wrapper for realpath.
Definition: util-path.c:221
PathIsRelative
int PathIsRelative(const char *path)
Check if a path is relative.
Definition: util-path.c:70
suricata.h
SCIsRegularFile
bool SCIsRegularFile(const struct dirent *const dir_entry)
OS independent to check for regular file.
Definition: util-path.c:205
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
debug.h
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:87
SCCreateDirectoryTree
int SCCreateDirectoryTree(const char *path, const bool final)
Recursively create a directory.
Definition: util-path.c:124