replace realpath.c with canonicalize.c

This commit is contained in:
IgnorantGuru 2012-06-03 09:29:28 -06:00
parent 478cbce475
commit 37f521494d
7 changed files with 134 additions and 103 deletions

View File

@ -1,6 +1,6 @@
noinst_PROGRAMS = udevil
udevil_SOURCES = udevil.c device-info.c realpath.c
udevil_SOURCES = udevil.c device-info.c canonicalize.c
bin_SCRIPTS = devmon

View File

@ -65,7 +65,7 @@ CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
PROGRAMS = $(noinst_PROGRAMS)
am_udevil_OBJECTS = udevil-udevil.$(OBJEXT) \
udevil-device-info.$(OBJEXT) udevil-realpath.$(OBJEXT)
udevil-device-info.$(OBJEXT) udevil-canonicalize.$(OBJEXT)
udevil_OBJECTS = $(am_udevil_OBJECTS)
am__DEPENDENCIES_1 =
udevil_DEPENDENCIES = $(am__DEPENDENCIES_1)
@ -276,7 +276,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
udevil_SOURCES = udevil.c device-info.c realpath.c
udevil_SOURCES = udevil.c device-info.c canonicalize.c
bin_SCRIPTS = devmon
INSTALL_DIR = $(DESTDIR)/$(prefix)/bin
INSTALL_SRC = $(top_builddir)/src
@ -378,8 +378,8 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udevil-canonicalize.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udevil-device-info.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udevil-realpath.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udevil-udevil.Po@am__quote@
.c.o:
@ -431,19 +431,19 @@ udevil-device-info.obj: device-info.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-device-info.obj `if test -f 'device-info.c'; then $(CYGPATH_W) 'device-info.c'; else $(CYGPATH_W) '$(srcdir)/device-info.c'; fi`
udevil-realpath.o: realpath.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -MT udevil-realpath.o -MD -MP -MF $(DEPDIR)/udevil-realpath.Tpo -c -o udevil-realpath.o `test -f 'realpath.c' || echo '$(srcdir)/'`realpath.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/udevil-realpath.Tpo $(DEPDIR)/udevil-realpath.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='realpath.c' object='udevil-realpath.o' libtool=no @AMDEPBACKSLASH@
udevil-canonicalize.o: canonicalize.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -MT udevil-canonicalize.o -MD -MP -MF $(DEPDIR)/udevil-canonicalize.Tpo -c -o udevil-canonicalize.o `test -f 'canonicalize.c' || echo '$(srcdir)/'`canonicalize.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/udevil-canonicalize.Tpo $(DEPDIR)/udevil-canonicalize.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='canonicalize.c' object='udevil-canonicalize.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-realpath.o `test -f 'realpath.c' || echo '$(srcdir)/'`realpath.c
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-canonicalize.o `test -f 'canonicalize.c' || echo '$(srcdir)/'`canonicalize.c
udevil-realpath.obj: realpath.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -MT udevil-realpath.obj -MD -MP -MF $(DEPDIR)/udevil-realpath.Tpo -c -o udevil-realpath.obj `if test -f 'realpath.c'; then $(CYGPATH_W) 'realpath.c'; else $(CYGPATH_W) '$(srcdir)/realpath.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/udevil-realpath.Tpo $(DEPDIR)/udevil-realpath.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='realpath.c' object='udevil-realpath.obj' libtool=no @AMDEPBACKSLASH@
udevil-canonicalize.obj: canonicalize.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -MT udevil-canonicalize.obj -MD -MP -MF $(DEPDIR)/udevil-canonicalize.Tpo -c -o udevil-canonicalize.obj `if test -f 'canonicalize.c'; then $(CYGPATH_W) 'canonicalize.c'; else $(CYGPATH_W) '$(srcdir)/canonicalize.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/udevil-canonicalize.Tpo $(DEPDIR)/udevil-canonicalize.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='canonicalize.c' object='udevil-canonicalize.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-realpath.obj `if test -f 'realpath.c'; then $(CYGPATH_W) 'realpath.c'; else $(CYGPATH_W) '$(srcdir)/realpath.c'; fi`
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(udevil_CFLAGS) $(CFLAGS) -c -o udevil-canonicalize.obj `if test -f 'canonicalize.c'; then $(CYGPATH_W) 'canonicalize.c'; else $(CYGPATH_W) '$(srcdir)/canonicalize.c'; fi`
mostlyclean-libtool:
-rm -f *.lo

View File

@ -1,5 +1,5 @@
/*
* realpath.c -- canonicalize pathname by removing symlinks
* canonicalize.c -- canonicalize pathname by removing symlinks
* Copyright (C) 1993 Rick Sladkey <jrs@world.std.com>
*
* This program is free software; you can redistribute it and/or modify
@ -11,53 +11,30 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library Public License for more details.
*
*/
#define resolve_symlinks
/*
* This routine is part of libc. We include it nevertheless,
* since the libc version has some security flaws.
*
* TODO: use canonicalize_file_name() when exist in glibc
*/
/*
This file was taken from the source code for mount.
*/
#include <limits.h> /* for PATH_MAX */
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "realpath.h"
#include <glib/gi18n.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#define MAX_READLINKS 32
#include "canonicalize.h"
#ifndef MAXSYMLINKS
# define MAXSYMLINKS 256
#endif
/* A small malloc extension, from mount */
void *
xmalloc (size_t size) {
void *t;
if (size == 0)
return NULL;
t = malloc(size);
if(! t)
{
fprintf(stderr, _("Error: out of memory\n"));
exit(5); /* Memory allocation error */
}
return t;
}
char *
private_realpath(const char *path, char *resolved_path, int maxreslth) {
static char *
myrealpath(const char *path, char *resolved_path, int maxreslth) {
int readlinks = 0;
char *npath;
char link_path[PATH_MAX+1];
@ -68,17 +45,14 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) {
/* If it's a relative pathname use getcwd for starters. */
if (*path != '/') {
if (!getcwd(npath, maxreslth-2)) {
//g_warning("realpath: could not get current directory: %s",
// strerror(errno) );
return NULL;
}
npath += strlen(npath);
if (npath[-1] != '/')
*npath++ = '/';
if (!getcwd(npath, maxreslth-2))
return NULL;
npath += strlen(npath);
if (npath[-1] != '/')
*npath++ = '/';
} else {
*npath++ = '/';
path++;
*npath++ = '/';
path++;
}
/* Expand each slash-separated pathname component. */
@ -112,7 +86,7 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) {
}
/* Protect against infinite loops. */
if (readlinks++ > MAX_READLINKS) {
if (readlinks++ > MAXSYMLINKS) {
errno = ELOOP;
goto err;
}
@ -125,8 +99,8 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) {
if (errno != EINVAL)
goto err;
} else {
#ifdef resolve_symlinks /* Richard Gooch dislikes sl resolution */
int m;
char *newbuf;
/* Note: readlink doesn't add the null byte. */
link_path[n] = '\0';
@ -140,13 +114,13 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) {
/* Insert symlink contents into path. */
m = strlen(path);
if (buf)
free(buf);
buf = xmalloc(m + n + 1);
memcpy(buf, link_path, n);
memcpy(buf + n, path, m + 1);
path = buf;
#endif
newbuf = malloc(m + n + 1);
if (!newbuf)
goto err;
memcpy(newbuf, link_path, n);
memcpy(newbuf + n, path, m + 1);
free(buf);
path = buf = newbuf;
}
*npath++ = '/';
}
@ -156,12 +130,76 @@ private_realpath(const char *path, char *resolved_path, int maxreslth) {
/* Make sure it's null terminated. */
*npath = '\0';
if (buf)
free(buf);
free(buf);
return resolved_path;
err:
if (buf)
free(buf);
free(buf);
return NULL;
}
/*
* Converts private "dm-N" names to "/dev/mapper/<name>"
*
* Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
* provides the real DM device names in /sys/block/<ptname>/dm/name
*/
char *
canonicalize_dm_name(const char *ptname)
{
FILE *f;
size_t sz;
char path[256], name[256], *res = NULL;
snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
if (!(f = fopen(path, "r")))
return NULL;
/* read "<name>\n" from sysfs */
if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
name[sz - 1] = '\0';
snprintf(path, sizeof(path), "/dev/mapper/%s", name);
res = strdup(path);
}
fclose(f);
return res;
}
char *
canonicalize_path(const char *path)
{
char canonical[PATH_MAX+2];
char *p;
if (path == NULL)
return NULL;
if (!myrealpath(path, canonical, PATH_MAX+1))
return strdup(path);
p = strrchr(canonical, '/');
if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
p = canonicalize_dm_name(p+1);
if (p)
return p;
}
return strdup(canonical);
}
#ifdef TEST_PROGRAM_CANONICALIZE
int main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "usage: %s <device>\n", argv[0]);
exit(EXIT_FAILURE);
}
fprintf(stdout, "orig: %s\n", argv[1]);
fprintf(stdout, "real: %s\n", canonicalize_path(argv[1]));
exit(EXIT_SUCCESS);
}
#endif

10
src/canonicalize.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef CANONICALIZE_H
#define CANONICALIZE_H
//#include "c.h" /* for PATH_MAX */
#include <limits.h> /* for PATH_MAX */
extern char *canonicalize_path(const char *path);
extern char *canonicalize_dm_name(const char *ptname);
#endif /* CANONICALIZE_H */

View File

@ -18,8 +18,6 @@
// intltool
#include <glib/gi18n.h>
// use mount's realpath
#include "realpath.h"
typedef struct device_t {

View File

@ -1,20 +0,0 @@
#ifndef _REAL_PATH_H
#define _REAL_PATH_H
/* a safer implementation of realpath. */
extern char *private_realpath(const char *path, char *resolved_path, int m);
#ifndef PATH_MAX
#define PATH_MAX 8192
#endif
/* And a macro to replace current calls, assuming that the buffer
size is PATH_MAX
*/
#ifdef realpath
#undef realpath
#endif
#define realpath(a,b) private_realpath(a,b,PATH_MAX)
#endif

View File

@ -51,8 +51,8 @@
// intltool
#include <glib/gi18n.h>
// use mount's realpath
#include "realpath.h"
// use mount's more secure version of realpath
#include "canonicalize.h"
#include "device-info.h"
@ -1361,8 +1361,6 @@ static char* get_ip( const char* hostname )
static gboolean get_realpath( char** path )
{
char res_path[PATH_MAX];
if ( !path || !*path || !( *path && *path[0] != '\0' ) )
{
if ( path )
@ -1373,10 +1371,17 @@ static gboolean get_realpath( char** path )
return FALSE;
}
if ( realpath( *path, res_path ) && res_path[0] == '/' )
char* res = canonicalize_path( *path );
if ( res && res[0] != '/' )
{
g_free( res );
res = NULL;
}
if ( res )
{
g_free( *path );
*path = g_strdup( res_path );
*path = res;
return TRUE;
}
else