path-util.c revision dfe2b5d36666dfc941821dadf59267d28ff58ff5
/* Copyright (c) 2009-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "str.h"
#include "path-util.h"
#include <unistd.h>
#define PATH_UTIL_MAX_SYMLINKS 80
{
/* @UNSAFE */
char *dir;
return -1;
}
}
return 0;
}
{
/* @UNSAFE */
unsigned int link_count = 0;
const char *p;
if (path[0] != '/') {
/* relative; initialize npath with current directory */
return -1;
} else {
/* absolute; initialize npath with root */
asize = 128;
npath[0] = '/';
}
p = path;
while (*p != '\0') {
const char *segend;
/* skip duplicate shashes */
while (*p == '/')
p++;
/* find end of path segment */
if (segend == p)
break; /* '\0' */
/* a reference to this segment; nothing to do */
/* a reference to parent segment; back up to previous
* slash */
npath_pos--;
}
} else {
/* make sure npath now ends in slash */
*(npath_pos++) = '/';
}
/* allocate space if necessary */
}
/* copy segment to normalized path */
}
if (resolve_links) {
/* stat path up to here (segend points to tail) */
*npath_pos = '\0';
return -1;
}
/* symlink */
char *npath_link;
/* limit link dereferences */
if (++link_count > PATH_UTIL_MAX_SYMLINKS) {
*error_r = "Too many symlink dereferences";
return -1;
}
/* allocate space for preserving tail of previous symlink and
first attempt at reading symlink with room for the tail
buffer will look like this:
[npath][0][preserved tail][link buffer][room for tail][0]
*/
}
if (ltlen > 0) {
/* preserve tail just after end of npath */
}
/* read the symlink after the preserved tail */
for (;;) {
/* attempt to read the link */
return -1;
}
/* make static analyzers happy */
break;
}
/* sum of new symlink content length
* and path tail length may not
exceed maximum */
*error_r = "Resulting path is too long";
return -1;
}
/* try again with bigger buffer,
we need to allocate more space as well if lsize == ret,
because the returned link may have gotten truncated */
}
}
/* add tail of previous path at end of symlink */
if (ltlen > 0) {
} else {
}
/* use as new source path */
if (path[0] == '/') {
/* absolute symlink; start over at root */
} else {
/* relative symlink; back up to previous segment */
npath_pos--;
}
}
/* not last segment, but not a directory either */
return -1;
}
}
p = segend;
}
/* remove any trailing slash */
npath_pos--;
*npath_pos = '\0';
return 0;
}
{
}
const char **error_r)
{
if (*path == '/')
}
{
}
const char **error_r)
{
if (*path == '/')
}
{
if (*path == '/') {
return 0;
}
return -1;
}
return 0;
}
{
if (*path == '/')
return path;
}
{
char *dir;
return -1;
return 0;
}
{
/* @UNSAFE */
char *dest;
}
if (ret < 0) {
return -1;
}
return 0;
}
{
if (**binpath == '/') {
/* already have absolute path */
return TRUE;
/* relative to current directory */
const char *error;
return FALSE;
}
return TRUE;
/* we have to find our executable from path */
return TRUE;
}
str_truncate(path, 0);
}
*error_r = "Could not find the wanted executable from PATH";
return FALSE;
} else {
*error_r = "PATH environment variable undefined";
return FALSE;
}
}