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 /**
32  * \brief Check if a path is absolute
33  *
34  * \param path string with the path
35  *
36  * \retval 1 absolute
37  * \retval 0 not absolute
38  */
39 int PathIsAbsolute(const char *path)
40 {
41  if (strlen(path) > 1 && path[0] == '/') {
42  return 1;
43  }
44 
45 #if (defined OS_WIN32 || defined __CYGWIN__)
46  if (strlen(path) > 2) {
47  if (isalpha((unsigned char)path[0]) && path[1] == ':') {
48  return 1;
49  }
50  }
51 #endif
52 
53  return 0;
54 }
55 
56 /**
57  * \brief Check if a path is relative
58  *
59  * \param path string with the path
60  *
61  * \retval 1 relative
62  * \retval 0 not relative
63  */
64 int PathIsRelative(const char *path)
65 {
66  return PathIsAbsolute(path) ? 0 : 1;
67 }
68 
69 /**
70  * \brief Wrapper to join a directory and filename and resolve using realpath
71  * _fullpath is used for WIN32
72  *
73  * \param out_buf output buffer. Up to PATH_MAX will be written. Unchanged on exit failure.
74  * \param buf_len length of output buffer
75  * \param dir the directory
76  * \param fname the filename
77  *
78  * \retval TM_ECODE_OK on success
79  * \retval TM_ECODE_FAILED on failure
80  */
81 TmEcode PathJoin (char *out_buf, uint16_t buf_len, const char *const dir, const char *const fname)
82 {
83  SCEnter();
84 #ifdef OS_WIN32
85 #define DIRECTORY_SEPARATOR '\\'
86 #else
87 #define DIRECTORY_SEPARATOR '/'
88 #endif
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(SC_ERR_SPRINTF, "Could not join filename to path");
94  }
95  char *tmp_buf = SCRealPath(out_buf, NULL);
96  if (tmp_buf == NULL) {
97  SCLogError(SC_ERR_SPRINTF, "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 }
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: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
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
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:39
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:220
PathIsRelative
int PathIsRelative(const char *path)
Check if a path is relative.
Definition: util-path.c:64
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: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:81
SCCreateDirectoryTree
int SCCreateDirectoryTree(const char *path, const bool final)
Recursively create a directory.
Definition: util-path.c:123