- use a private buffer to resolve symlinks, the previous code was broken
- factored out symlink handling - handle relative symlinks now - handle device paths that do not contain a '/'.
This commit is contained in:
parent
0e7abd5a0f
commit
26dae55653
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: getdiskrawname.c,v 1.2 2013/12/22 14:31:51 mlelstv Exp $ */
|
/* $NetBSD: getdiskrawname.c,v 1.3 2014/09/12 07:59:36 mlelstv Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
* Copyright (c) 2012 The NetBSD Foundation, Inc.
|
||||||
@ -29,7 +29,7 @@
|
|||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__RCSID("$NetBSD: getdiskrawname.c,v 1.2 2013/12/22 14:31:51 mlelstv Exp $");
|
__RCSID("$NetBSD: getdiskrawname.c,v 1.3 2014/09/12 07:59:36 mlelstv Exp $");
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
@ -37,25 +37,51 @@ __RCSID("$NetBSD: getdiskrawname.c,v 1.2 2013/12/22 14:31:51 mlelstv Exp $");
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
resolve_link(char *buf, size_t bufsiz, const char *name)
|
||||||
|
{
|
||||||
|
const char *dp;
|
||||||
|
ssize_t nlen, dlen;
|
||||||
|
|
||||||
|
dlen = readlink(name, buf, bufsiz-1);
|
||||||
|
if (dlen == -1)
|
||||||
|
return name;
|
||||||
|
|
||||||
|
buf[dlen] = '\0';
|
||||||
|
|
||||||
|
if (buf[0] != '/') {
|
||||||
|
dp = strrchr(name, '/');
|
||||||
|
if (dp != NULL) {
|
||||||
|
nlen = dp - name + 1;
|
||||||
|
if (nlen + 1 > PATH_MAX)
|
||||||
|
return NULL;
|
||||||
|
if (nlen + dlen + 1 > PATH_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memmove(buf+nlen, buf, dlen+1);
|
||||||
|
memcpy(buf, name, nlen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
getdiskrawname(char *buf, size_t bufsiz, const char *name)
|
getdiskrawname(char *buf, size_t bufsiz, const char *name)
|
||||||
{
|
{
|
||||||
const char *dp = strrchr(name, '/');
|
const char *dp;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
ssize_t len;
|
char dest[PATH_MAX];
|
||||||
|
|
||||||
if (dp == NULL) {
|
if ((name = resolve_link(dest, sizeof(dest), name)) == NULL) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = readlink(name, buf, bufsiz-1);
|
dp = strrchr(name, '/');
|
||||||
if (len > 0) {
|
|
||||||
buf[len] = '\0';
|
|
||||||
name = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(name, &st) == -1)
|
if (stat(name, &st) == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -65,7 +91,10 @@ getdiskrawname(char *buf, size_t bufsiz, const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dp != NULL)
|
||||||
(void)snprintf(buf, bufsiz, "%.*s/r%s", (int)(dp - name), name, dp + 1);
|
(void)snprintf(buf, bufsiz, "%.*s/r%s", (int)(dp - name), name, dp + 1);
|
||||||
|
else
|
||||||
|
(void)snprintf(buf, bufsiz, "r%s", name);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
@ -75,17 +104,18 @@ getdiskcookedname(char *buf, size_t bufsiz, const char *name)
|
|||||||
{
|
{
|
||||||
const char *dp;
|
const char *dp;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
ssize_t len;
|
char dest[PATH_MAX];
|
||||||
|
|
||||||
if ((dp = strrchr(name, '/')) == NULL) {
|
if ((name = resolve_link(dest, sizeof(dest), name)) == NULL) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = readlink(name, buf, bufsiz-1);
|
dp = strrchr(name, '/');
|
||||||
if (len > 0) {
|
|
||||||
buf[len] = '\0';
|
if ((dp != NULL && dp[1] != 'r') || (dp == NULL && name[0] != 'r')) {
|
||||||
name = buf;
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stat(name, &st) == -1)
|
if (stat(name, &st) == -1)
|
||||||
@ -96,12 +126,10 @@ getdiskcookedname(char *buf, size_t bufsiz, const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dp[1] != 'r') {
|
if (dp != NULL)
|
||||||
errno = EINVAL;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)snprintf(buf, bufsiz, "%.*s/%s", (int)(dp - name), name, dp + 2);
|
(void)snprintf(buf, bufsiz, "%.*s/%s", (int)(dp - name), name, dp + 2);
|
||||||
|
else
|
||||||
|
(void)snprintf(buf, bufsiz, "%s", name + 1);
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user