cdio_follow_symlink -> cdio_realpath which is really POSIX realpath. (Suggestion via Thomas Schmitt.) gnu_linux.c: report errors when they occur.

This commit is contained in:
R. Bernstein
2010-01-16 16:44:12 -05:00
parent 2103e77696
commit 7d8b6d0a4d
9 changed files with 51 additions and 40 deletions

View File

@@ -491,7 +491,7 @@ AC_SUBST(LIBCDIO_SOURCE_PATH)
AC_CHECK_FUNCS( [bzero drand48 ftruncate geteuid getgid \
getuid getpwuid gettimeofday lstat memcpy memset \
rand seteuid setegid snprintf setenv unsetenv tzset \
sleep vsnprintf readlink gmtime_r localtime_r] )
sleep vsnprintf readlink realpath gmtime_r localtime_r] )
# check for timegm() support
AC_CHECK_FUNC(timegm, AC_DEFINE(HAVE_TIMEGM,1,

View File

@@ -1,7 +1,5 @@
/*
$Id: util.h,v 1.12 2008/03/25 15:59:10 karl Exp $
Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2004, 2005, 2006, 2008, 2010 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify
@@ -28,6 +26,7 @@
Warning: this will probably get removed/replaced by using glib.h
*/
#include <stdlib.h>
#include <cdio/types.h>
#undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
@@ -99,7 +98,13 @@ _cdio_strsplit(const char str[], char delim);
uint8_t cdio_to_bcd8(uint8_t n);
uint8_t cdio_from_bcd8(uint8_t p);
void cdio_follow_symlink (const char * src, char * dst);
/*! cdio_realpath() same as POSIX.1-2001 realpath if that's
around. If not we do poor-man's simulation of that behavior. */
char *cdio_realpath (const char *psz_src, char *psz_dst);
#ifdef WANT_FOLLOW_SYMLINK_COMPATIBILITY
# define cdio_follow_symlink cdio_realpath
#endif
#ifdef __cplusplus
}

View File

@@ -1,6 +1,4 @@
# $Id: Makefile.am,v 1.28 2008/10/20 01:25:15 rocky Exp $
#
# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
# Rocky Bernstein <rocky@gnu.org>
#
# This program is free software: you can redistribute it and/or modify
@@ -67,7 +65,6 @@ libcdio_sources = \
device.c \
disc.c \
ds.c \
follow_symlink.c \
FreeBSD/freebsd.c \
FreeBSD/freebsd.h \
FreeBSD/freebsd_cam.c \
@@ -93,6 +90,7 @@ libcdio_sources = \
os2.c \
osx.c \
read.c \
realpath.c \
sector.c \
solaris.c \
track.c \

View File

@@ -230,10 +230,10 @@ cdio_add_device_list(char **device_list[], const char *drive,
unsigned int j;
char real_device_1[PATH_MAX];
char real_device_2[PATH_MAX];
cdio_follow_symlink(drive, real_device_1);
cdio_realpath(drive, real_device_1);
/* Check if drive is already in list. */
for (j=0; j<*num_drives; j++) {
cdio_follow_symlink((*device_list)[j], real_device_2);
cdio_realpath((*device_list)[j], real_device_2);
if (strcmp(real_device_1, real_device_2) == 0) break;
}

View File

@@ -636,12 +636,18 @@ static int is_mounted (const char * device, char * target) {
if(!fp) return 0;
/* Get real device */
cdio_follow_symlink(device, real_device_1);
if (NULL == cdio_realpath(device, real_device_1)) {
cdio_warn("Problems resolving device %s: %s\n", device, strerror(errno));
}
/* Read entries */
while ( fscanf(fp, "%s %s %*s %*s %*d %*d\n", file_device, file_target) != EOF ) {
cdio_follow_symlink(file_device, real_device_2);
if (NULL == cdio_realpath(file_device, real_device_2)) {
cdio_warn("Problems resolving device %s: %s\n",
file_device, strerror(errno));
}
if(!strcmp(real_device_1, real_device_2)) {
strcpy(target, file_target);
fclose(fp);

View File

@@ -18,15 +18,15 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
Resolves symbolic links.
POSIX realpath if that's around, and something like it if not.
To compile as a standalone program:
gcc -Wall -g -I../.. -DHAVE_CONFIG_H -DSTANDALONE -o follow_symlink follow_symlink.c
gcc -Wall -g -I../.. -DHAVE_CONFIG_H -DSTANDALONE -o realpath realpath.c
*/
/*
Make sure we handle:
- resolve relative links like /dev/cdrom -> sr2
- abort on deep link nesting /dev/cdrom -> /dev/cdrom
- abort on cyclic linking like /dev/cdrom -> /dev/cdrom
*/
#ifdef HAVE_CONFIG_H
@@ -62,28 +62,30 @@
#define PATH_MAX 4096
#endif
/*!
Follow symlinks until we have the real device file
(idea taken from libunieject).
*/
#include <cdio/util.h>
void cdio_follow_symlink (const char * src, char * dst) {
#ifdef HAVE_READLINK
/*! cdio_realpath() same as POSIX.1-2001 realpath if that's
around. If not we do poor-man's simulation of that behavior. */
char *cdio_realpath (const char *psz_src_path, char *psz_resolved_path) {
#ifdef HAVE_REALPATH
psz_resolved_path = realpath(psz_src_path, psz_resolved_path);
#elif defined(HAVE_READLINK)
char tmp_src[PATH_MAX+1];
char tmp_dst[PATH_MAX+1];
char *p_adr;
int link_loop_limit = 100, i;
int len;
int i, len;
const int loop_limit = 100;
strcpy(tmp_src, src);
strcpy(tmp_src, psz_src_path);
/* FIXME:
remove loop and change with stat before and after readlink
which looks direct symlink. Rely on errno to figure out other
non-existent or looped symlinks.
*/
for(i = 0; i < link_loop_limit; i++) {
for(i = 0; i < loop_limit; i++) {
len = readlink(tmp_src, tmp_dst, PATH_MAX);
if (-1 == len) {
/* Right now we expect a "not symlink" error. However after
@@ -93,7 +95,6 @@ void cdio_follow_symlink (const char * src, char * dst) {
break;
} else {
tmp_dst[len] = '\0';
if (tmp_dst[0] != '/') {
/* Take care of relative link like /dev/cdrom -> sr2 */
p_adr = strrchr(tmp_src, '/');
@@ -108,11 +109,12 @@ void cdio_follow_symlink (const char * src, char * dst) {
tmp_src[PATH_MAX - 1] = 0; /* strncpy() does not always set a 0 */
}
}
strncpy(dst, tmp_src, PATH_MAX);
strncpy(psz_resolved_path, tmp_src, PATH_MAX);
#else
strncpy(dst, src, PATH_MAX);
strncpy(psz_resolved_path, psz_src_path, PATH_MAX);
#endif
return psz_resolved_path;
}
@@ -130,7 +132,7 @@ int main(int argc, char **argv)
}
for (i= 1; i < argc; i++) {
dest[0] = 0;
cdio_follow_symlink (argv[i], dest);
cdio_realpath (argv[i], dest);
printf("%s -> %s\n", argv[i], dest);
}
exit(0);

View File

@@ -779,7 +779,7 @@ _iso9660_dir_to_statbuf (iso9660_dir_t *p_iso9660_dir, bool_3way_t b_xa,
calloc(1, sizeof(iso9660_stat_t)+i_rr_fname+2);
if (!p_stat_new)
{
cdio_warn("Couldn't calloc(1, %d)", sizeof(iso9660_stat_t)+i_rr_fname+2);
cdio_warn("Couldn't calloc(1, %zd)", sizeof(iso9660_stat_t)+i_rr_fname+2);
return NULL;
}
memcpy(p_stat_new, p_stat, stat_len);

View File

@@ -18,8 +18,8 @@ INCLUDES = -I$(top_srcdir) $(LIBCDIO_CFLAGS) $(LIBISO9660_CFLAGS)
freebsd_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
freebsd_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
follow_symlink_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
follow_symlink_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
realpath_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
realpath_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
gnu_linux_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
gnu_linux_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
@@ -36,7 +36,7 @@ solaris_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
win32_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
win32_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
check_PROGRAMS = follow_symlink freebsd gnu_linux mmc osx solaris win32
check_PROGRAMS = freebsd gnu_linux mmc osx realpath solaris win32
TESTS = $(check_PROGRAMS)

View File

@@ -121,9 +121,9 @@ main(int argc, const char *argv[])
if (0 == rc) {
/* Just when you thought we'd forgotten, here is our first
test! */
cdio_follow_symlink(psz_symlink_file, psz_file_check);
cdio_realpath(psz_symlink_file, psz_file_check);
if (0 != strncmp(psz_file_check, psz_orig_file, PATH_MAX)) {
fprintf(stderr, "simple cdio_follow_symlink failed. %s vs %s\n",
fprintf(stderr, "simple cdio_realpath failed: %s vs %s\n",
psz_file_check, psz_orig_file);
exit(1);
}
@@ -134,9 +134,9 @@ main(int argc, const char *argv[])
rc = check_rc(symlink(psz_symlink_file, psz_symlink_file),
"symlink", psz_symlink_file);
if (0 == rc) {
cdio_follow_symlink(psz_symlink_file, psz_file_check);
cdio_realpath(psz_symlink_file, psz_file_check);
if (0 != strncmp(psz_file_check, psz_symlink_file, PATH_MAX)) {
fprintf(stderr, "direct cdio_follow_symlink cycle test failed. %s vs %s\n",
fprintf(stderr, "direct cdio_realpath cycle test failed. %s vs %s\n",
psz_file_check, psz_orig_file);
exit(2);
}