path: Move path related utility functions to separate files

This commit is contained in:
Martin Willi 2015-04-15 16:29:18 +02:00
parent 7585a85f1a
commit 001a22e2c1
6 changed files with 249 additions and 201 deletions

View File

@ -41,7 +41,7 @@ utils/utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.c \
utils/lexparser.c utils/optionsfrom.c utils/capabilities.c utils/backtrace.c \
utils/parser_helper.c utils/test.c utils/process.c utils/utils/strerror.c \
utils/utils/atomics.c utils/utils/string.c utils/utils/memory.c \
utils/utils/tty.c
utils/utils/tty.c utils/utils/path.c
libstrongswan_la_SOURCES += \
threading/thread.c \

View File

@ -39,7 +39,7 @@ utils/utils.c utils/chunk.c utils/debug.c utils/enum.c utils/identification.c \
utils/lexparser.c utils/optionsfrom.c utils/capabilities.c utils/backtrace.c \
utils/parser_helper.c utils/test.c utils/process.c utils/utils/strerror.c \
utils/utils/atomics.c utils/utils/string.c utils/utils/memory.c \
utils/utils/tty.c
utils/utils/tty.c utils/utils/path.c
if !USE_WINDOWS
libstrongswan_la_SOURCES += \
@ -110,7 +110,7 @@ utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \
utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \
utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h \
utils/utils/atomics.h utils/utils/types.h utils/utils/byteorder.h \
utils/utils/string.h utils/utils/memory.h utils/utils/tty.h
utils/utils/string.h utils/utils/memory.h utils/utils/tty.h utils/utils/path.h
endif
library.lo : $(top_builddir)/config.status

View File

@ -14,7 +14,6 @@
* for more details.
*/
#define _GNU_SOURCE /* for memrchr */
#ifdef WIN32
/* for GetTickCount64, Windows 7 */
# define _WIN32_WINNT 0x0601
@ -22,13 +21,11 @@
#include "utils.h"
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
#include <stdint.h>
#include <limits.h>
#include <dirent.h>
#include <time.h>
#ifndef WIN32
@ -179,149 +176,6 @@ void wait_sigint()
#endif
/**
* Described in header.
*/
char* path_dirname(const char *path)
{
char *pos;
pos = path ? strrchr(path, DIRECTORY_SEPARATOR[0]) : NULL;
if (pos && !pos[1])
{ /* if path ends with slashes we have to look beyond them */
while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip trailing slashes */
pos--;
}
pos = memrchr(path, DIRECTORY_SEPARATOR[0], pos - path + 1);
}
if (!pos)
{
#ifdef WIN32
if (path && strlen(path))
{
if ((isalpha(path[0]) && path[1] == ':'))
{ /* if just a drive letter given, return that as dirname */
return chunk_clone(chunk_from_chars(path[0], ':', 0)).ptr;
}
}
#endif
return strdup(".");
}
while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip superfluous slashes */
pos--;
}
return strndup(path, pos - path + 1);
}
/**
* Described in header.
*/
char* path_basename(const char *path)
{
char *pos, *trail = NULL;
if (!path || !*path)
{
return strdup(".");
}
pos = strrchr(path, DIRECTORY_SEPARATOR[0]);
if (pos && !pos[1])
{ /* if path ends with slashes we have to look beyond them */
while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip trailing slashes */
pos--;
}
if (pos == path && *pos == DIRECTORY_SEPARATOR[0])
{ /* contains only slashes */
return strdup(DIRECTORY_SEPARATOR);
}
trail = pos + 1;
pos = memrchr(path, DIRECTORY_SEPARATOR[0], trail - path);
}
pos = pos ? pos + 1 : (char*)path;
return trail ? strndup(pos, trail - pos) : strdup(pos);
}
/**
* Described in header.
*/
bool path_absolute(const char *path)
{
if (!path)
{
return FALSE;
}
#ifdef WIN32
if (strpfx(path, "\\\\"))
{ /* UNC */
return TRUE;
}
if (strlen(path) && isalpha(path[0]) && path[1] == ':')
{ /* drive letter */
return TRUE;
}
#else /* !WIN32 */
if (path[0] == DIRECTORY_SEPARATOR[0])
{
return TRUE;
}
#endif
return FALSE;
}
/**
* Described in header.
*/
bool mkdir_p(const char *path, mode_t mode)
{
int len;
char *pos, full[PATH_MAX];
pos = full;
if (!path || *path == '\0')
{
return TRUE;
}
len = snprintf(full, sizeof(full)-1, "%s", path);
if (len < 0 || len >= sizeof(full)-1)
{
DBG1(DBG_LIB, "path string %s too long", path);
return FALSE;
}
/* ensure that the path ends with a '/' */
if (full[len-1] != '/')
{
full[len++] = '/';
full[len] = '\0';
}
/* skip '/' at the beginning */
while (*pos == '/')
{
pos++;
}
while ((pos = strchr(pos, '/')))
{
*pos = '\0';
if (access(full, F_OK) < 0)
{
#ifdef WIN32
if (_mkdir(full) < 0)
#else
if (mkdir(full, mode) < 0)
#endif
{
DBG1(DBG_LIB, "failed to create directory %s", full);
return FALSE;
}
}
*pos = '/';
pos++;
}
return TRUE;
}
#ifndef HAVE_CLOSEFROM
/**
* Described in header.

View File

@ -81,20 +81,12 @@
#include "utils/string.h"
#include "utils/memory.h"
#include "utils/strerror.h"
#include "utils/path.h"
#include "utils/tty.h"
#ifdef __APPLE__
# include "compat/apple.h"
#endif
/**
* Directory separator character in paths on this platform
*/
#ifdef WIN32
# define DIRECTORY_SEPARATOR "\\"
#else
# define DIRECTORY_SEPARATOR "/"
#endif
/**
* Initialize utility functions
*/
@ -389,49 +381,6 @@ void free_align(void *ptr);
*/
void wait_sigint();
/**
* Like dirname(3) returns the directory part of the given null-terminated
* pathname, up to but not including the final '/' (or '.' if no '/' is found).
* Trailing '/' are not counted as part of the pathname.
*
* The difference is that it does this in a thread-safe manner (i.e. it does not
* use static buffers) and does not modify the original path.
*
* @param path original pathname
* @return allocated directory component
*/
char *path_dirname(const char *path);
/**
* Like basename(3) returns the filename part of the given null-terminated path,
* i.e. the part following the final '/' (or '.' if path is empty or NULL).
* Trailing '/' are not counted as part of the pathname.
*
* The difference is that it does this in a thread-safe manner (i.e. it does not
* use static buffers) and does not modify the original path.
*
* @param path original pathname
* @return allocated filename component
*/
char *path_basename(const char *path);
/**
* Check if a given path is absolute.
*
* @param path path to check
* @return TRUE if absolute, FALSE if relative
*/
bool path_absolute(const char *path);
/**
* Creates a directory and all required parent directories.
*
* @param path path to the new directory
* @param mode permissions of the new directory/directories
* @return TRUE on success
*/
bool mkdir_p(const char *path, mode_t mode);
#ifndef HAVE_CLOSEFROM
/**
* Close open file descriptors greater than or equal to lowfd.

View File

@ -0,0 +1,168 @@
/*
* Copyright (C) 2008-2014 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#define _GNU_SOURCE /* for memrchr */
#include <utils/utils.h>
#include <utils/debug.h>
#include <utils/chunk.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
/**
* Described in header.
*/
char* path_dirname(const char *path)
{
char *pos;
pos = path ? strrchr(path, DIRECTORY_SEPARATOR[0]) : NULL;
if (pos && !pos[1])
{ /* if path ends with slashes we have to look beyond them */
while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip trailing slashes */
pos--;
}
pos = memrchr(path, DIRECTORY_SEPARATOR[0], pos - path + 1);
}
if (!pos)
{
#ifdef WIN32
if (path && strlen(path))
{
if ((isalpha(path[0]) && path[1] == ':'))
{ /* if just a drive letter given, return that as dirname */
return chunk_clone(chunk_from_chars(path[0], ':', 0)).ptr;
}
}
#endif
return strdup(".");
}
while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip superfluous slashes */
pos--;
}
return strndup(path, pos - path + 1);
}
/**
* Described in header.
*/
char* path_basename(const char *path)
{
char *pos, *trail = NULL;
if (!path || !*path)
{
return strdup(".");
}
pos = strrchr(path, DIRECTORY_SEPARATOR[0]);
if (pos && !pos[1])
{ /* if path ends with slashes we have to look beyond them */
while (pos > path && *pos == DIRECTORY_SEPARATOR[0])
{ /* skip trailing slashes */
pos--;
}
if (pos == path && *pos == DIRECTORY_SEPARATOR[0])
{ /* contains only slashes */
return strdup(DIRECTORY_SEPARATOR);
}
trail = pos + 1;
pos = memrchr(path, DIRECTORY_SEPARATOR[0], trail - path);
}
pos = pos ? pos + 1 : (char*)path;
return trail ? strndup(pos, trail - pos) : strdup(pos);
}
/**
* Described in header.
*/
bool path_absolute(const char *path)
{
if (!path)
{
return FALSE;
}
#ifdef WIN32
if (strpfx(path, "\\\\"))
{ /* UNC */
return TRUE;
}
if (strlen(path) && isalpha(path[0]) && path[1] == ':')
{ /* drive letter */
return TRUE;
}
#else /* !WIN32 */
if (path[0] == DIRECTORY_SEPARATOR[0])
{
return TRUE;
}
#endif
return FALSE;
}
/**
* Described in header.
*/
bool mkdir_p(const char *path, mode_t mode)
{
int len;
char *pos, full[PATH_MAX];
pos = full;
if (!path || *path == '\0')
{
return TRUE;
}
len = snprintf(full, sizeof(full)-1, "%s", path);
if (len < 0 || len >= sizeof(full)-1)
{
DBG1(DBG_LIB, "path string %s too long", path);
return FALSE;
}
/* ensure that the path ends with a '/' */
if (full[len-1] != '/')
{
full[len++] = '/';
full[len] = '\0';
}
/* skip '/' at the beginning */
while (*pos == '/')
{
pos++;
}
while ((pos = strchr(pos, '/')))
{
*pos = '\0';
if (access(full, F_OK) < 0)
{
#ifdef WIN32
if (_mkdir(full) < 0)
#else
if (mkdir(full, mode) < 0)
#endif
{
DBG1(DBG_LIB, "failed to create directory %s", full);
return FALSE;
}
}
*pos = '/';
pos++;
}
return TRUE;
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2008-2014 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup path_i path
* @{ @ingroup utils_i
*/
#ifndef PATH_H_
#define PATH_H_
/**
* Directory separator character in paths on this platform
*/
#ifdef WIN32
# define DIRECTORY_SEPARATOR "\\"
#else
# define DIRECTORY_SEPARATOR "/"
#endif
/**
* Like dirname(3) returns the directory part of the given null-terminated
* pathname, up to but not including the final '/' (or '.' if no '/' is found).
* Trailing '/' are not counted as part of the pathname.
*
* The difference is that it does this in a thread-safe manner (i.e. it does not
* use static buffers) and does not modify the original path.
*
* @param path original pathname
* @return allocated directory component
*/
char *path_dirname(const char *path);
/**
* Like basename(3) returns the filename part of the given null-terminated path,
* i.e. the part following the final '/' (or '.' if path is empty or NULL).
* Trailing '/' are not counted as part of the pathname.
*
* The difference is that it does this in a thread-safe manner (i.e. it does not
* use static buffers) and does not modify the original path.
*
* @param path original pathname
* @return allocated filename component
*/
char *path_basename(const char *path);
/**
* Check if a given path is absolute.
*
* @param path path to check
* @return TRUE if absolute, FALSE if relative
*/
bool path_absolute(const char *path);
/**
* Creates a directory and all required parent directories.
*
* @param path path to the new directory
* @param mode permissions of the new directory/directories
* @return TRUE on success
*/
bool mkdir_p(const char *path, mode_t mode);
#endif /** PATH_H_ @} */