path: new funcs to merge paths

Take windows directory separators into account.

Path is not checked or "resolved".
pull/9381/head
Victor Julien 3 years ago
parent 269f751d36
commit 228caa640b

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2012 Open Information Security Foundation /* Copyright (C) 2007-2023 Open Information Security Foundation
* *
* You can copy, redistribute or modify this Program under the terms of * You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free * the GNU General Public License version 2 as published by the Free
@ -71,36 +71,86 @@ int PathIsRelative(const char *path)
return PathIsAbsolute(path) ? 0 : 1; return PathIsAbsolute(path) ? 0 : 1;
} }
int PathMerge(char *out_buf, size_t buf_size, const char *const dir, const char *const fname)
{
char path[PATH_MAX];
if (dir == NULL || strlen(dir) == 0)
return -1;
size_t r = strlcpy(path, dir, sizeof(path));
if (r >= sizeof(path)) {
return -1;
}
#if defined OS_WIN32 || defined __CYGWIN__
if (path[strlen(path) - 1] != '\\')
r = strlcat(path, "\\\\", sizeof(path));
#else
if (path[strlen(path) - 1] != '/')
r = strlcat(path, "/", sizeof(path));
#endif
if (r >= sizeof(path)) {
return -1;
}
r = strlcat(path, fname, sizeof(path));
if (r >= sizeof(path)) {
return -1;
}
r = strlcpy(out_buf, path, buf_size);
if (r >= buf_size) {
return -1;
}
return 0;
}
char *PathMergeAlloc(const char *const dir, const char *const fname)
{
char path[PATH_MAX];
if (PathMerge(path, sizeof(path), dir, fname) != 0)
return NULL;
char *ret = SCStrdup(path);
if (ret == NULL)
return NULL;
return ret;
}
/** /**
* \brief Wrapper to join a directory and filename and resolve using realpath * \brief Wrapper to join a directory and filename and resolve using realpath
* _fullpath is used for WIN32 * _fullpath is used for WIN32
* *
* \param out_buf output buffer. Up to PATH_MAX will be written. Unchanged on exit failure. * \param out_buf output buffer. Up to PATH_MAX will be written. Unchanged on exit failure.
* \param buf_len length of output buffer * \param buf_size length of output buffer, must be PATH_MAX
* \param dir the directory * \param dir the directory
* \param fname the filename * \param fname the filename
* *
* \retval TM_ECODE_OK on success * \retval 0 on success
* \retval TM_ECODE_FAILED on failure * \retval -1 on failure
*/ */
TmEcode PathJoin (char *out_buf, uint16_t buf_len, const char *const dir, const char *const fname) int PathJoin(char *out_buf, size_t buf_size, const char *const dir, const char *const fname)
{ {
SCEnter(); SCEnter();
uint16_t max_path_len = MAX(buf_len, PATH_MAX); if (buf_size != PATH_MAX) {
int bytes_written = snprintf(out_buf, max_path_len, "%s%c%s", dir, DIRECTORY_SEPARATOR, fname); return -1;
if (bytes_written <= 0) { }
if (PathMerge(out_buf, buf_size, dir, fname) != 0) {
SCLogError("Could not join filename to path"); SCLogError("Could not join filename to path");
SCReturnInt(TM_ECODE_FAILED); return -1;
} }
char *tmp_buf = SCRealPath(out_buf, NULL); char *tmp_buf = SCRealPath(out_buf, NULL);
if (tmp_buf == NULL) { if (tmp_buf == NULL) {
SCLogError("Error resolving path: %s", strerror(errno)); SCLogError("Error resolving path: %s", strerror(errno));
SCReturnInt(TM_ECODE_FAILED); return -1;
} }
memset(out_buf, 0, buf_len); memset(out_buf, 0, buf_size);
strlcpy(out_buf, tmp_buf, max_path_len); size_t ret = strlcpy(out_buf, tmp_buf, buf_size);
free(tmp_buf); free(tmp_buf);
SCReturnInt(TM_ECODE_OK); if (ret >= buf_size) {
return -1;
}
return 0;
} }
/** /**

@ -35,6 +35,12 @@ typedef struct stat SCStat;
#define SCStatFn(pathname, statbuf) stat((pathname), (statbuf)) #define SCStatFn(pathname, statbuf) stat((pathname), (statbuf))
#endif #endif
#if defined OS_WIN32 || defined __CYGWIN__
#define PATH_SEPARATOR_SIZE 2
#else
#define PATH_SEPARATOR_SIZE 1
#endif
#ifndef HAVE_NON_POSIX_MKDIR #ifndef HAVE_NON_POSIX_MKDIR
#define SCMkDir(a, b) mkdir(a, b) #define SCMkDir(a, b) mkdir(a, b)
#else #else
@ -43,7 +49,9 @@ typedef struct stat SCStat;
int PathIsAbsolute(const char *); int PathIsAbsolute(const char *);
int PathIsRelative(const char *); int PathIsRelative(const char *);
TmEcode PathJoin (char *out_buf, uint16_t buf_len, const char *const dir, const char *const fname); int PathMerge(char *out_buf, size_t buf_size, const char *const dir, const char *const fname);
char *PathMergeAlloc(const char *const dir, const char *const fname);
int PathJoin(char *out_buf, size_t buf_len, const char *const dir, const char *const fname);
int SCDefaultMkDir(const char *path); int SCDefaultMkDir(const char *path);
int SCCreateDirectoryTree(const char *path, const bool final); int SCCreateDirectoryTree(const char *path, const bool final);
bool SCPathExists(const char *path); bool SCPathExists(const char *path);

Loading…
Cancel
Save