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 \ AC_CHECK_FUNCS( [bzero drand48 ftruncate geteuid getgid \
getuid getpwuid gettimeofday lstat memcpy memset \ getuid getpwuid gettimeofday lstat memcpy memset \
rand seteuid setegid snprintf setenv unsetenv tzset \ 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 # check for timegm() support
AC_CHECK_FUNC(timegm, AC_DEFINE(HAVE_TIMEGM,1, 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, 2010 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2004, 2005, 2006, 2008 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2000 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify 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 Warning: this will probably get removed/replaced by using glib.h
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <cdio/types.h>
#undef MAX #undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #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_to_bcd8(uint8_t n);
uint8_t cdio_from_bcd8(uint8_t p); 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 #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, 2010
#
# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Rocky Bernstein <rocky@gnu.org> # Rocky Bernstein <rocky@gnu.org>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@@ -67,7 +65,6 @@ libcdio_sources = \
device.c \ device.c \
disc.c \ disc.c \
ds.c \ ds.c \
follow_symlink.c \
FreeBSD/freebsd.c \ FreeBSD/freebsd.c \
FreeBSD/freebsd.h \ FreeBSD/freebsd.h \
FreeBSD/freebsd_cam.c \ FreeBSD/freebsd_cam.c \
@@ -93,6 +90,7 @@ libcdio_sources = \
os2.c \ os2.c \
osx.c \ osx.c \
read.c \ read.c \
realpath.c \
sector.c \ sector.c \
solaris.c \ solaris.c \
track.c \ track.c \

View File

@@ -230,10 +230,10 @@ cdio_add_device_list(char **device_list[], const char *drive,
unsigned int j; unsigned int j;
char real_device_1[PATH_MAX]; char real_device_1[PATH_MAX];
char real_device_2[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. */ /* Check if drive is already in list. */
for (j=0; j<*num_drives; j++) { 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; 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; if(!fp) return 0;
/* Get real device */ /* 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 */ /* Read entries */
while ( fscanf(fp, "%s %s %*s %*s %*d %*d\n", file_device, file_target) != EOF ) { 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)) { if(!strcmp(real_device_1, real_device_2)) {
strcpy(target, file_target); strcpy(target, file_target);
fclose(fp); fclose(fp);

View File

@@ -18,15 +18,15 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. 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: 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: Make sure we handle:
- resolve relative links like /dev/cdrom -> sr2 - 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 #ifdef HAVE_CONFIG_H
@@ -62,28 +62,30 @@
#define PATH_MAX 4096 #define PATH_MAX 4096
#endif #endif
/*! #include <cdio/util.h>
Follow symlinks until we have the real device file
(idea taken from libunieject).
*/
void cdio_follow_symlink (const char * src, char * dst) { /*! cdio_realpath() same as POSIX.1-2001 realpath if that's
#ifdef HAVE_READLINK 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_src[PATH_MAX+1];
char tmp_dst[PATH_MAX+1]; char tmp_dst[PATH_MAX+1];
char *p_adr; char *p_adr;
int link_loop_limit = 100, i; int i, len;
int len; const int loop_limit = 100;
strcpy(tmp_src, src); strcpy(tmp_src, psz_src_path);
/* FIXME: /* FIXME:
remove loop and change with stat before and after readlink remove loop and change with stat before and after readlink
which looks direct symlink. Rely on errno to figure out other which looks direct symlink. Rely on errno to figure out other
non-existent or looped symlinks. 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); len = readlink(tmp_src, tmp_dst, PATH_MAX);
if (-1 == len) { if (-1 == len) {
/* Right now we expect a "not symlink" error. However after /* Right now we expect a "not symlink" error. However after
@@ -93,7 +95,6 @@ void cdio_follow_symlink (const char * src, char * dst) {
break; break;
} else { } else {
tmp_dst[len] = '\0'; tmp_dst[len] = '\0';
if (tmp_dst[0] != '/') { if (tmp_dst[0] != '/') {
/* Take care of relative link like /dev/cdrom -> sr2 */ /* Take care of relative link like /dev/cdrom -> sr2 */
p_adr = strrchr(tmp_src, '/'); 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 */ 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 #else
strncpy(dst, src, PATH_MAX); strncpy(psz_resolved_path, psz_src_path, PATH_MAX);
#endif #endif
return psz_resolved_path;
} }
@@ -130,7 +132,7 @@ int main(int argc, char **argv)
} }
for (i= 1; i < argc; i++) { for (i= 1; i < argc; i++) {
dest[0] = 0; dest[0] = 0;
cdio_follow_symlink (argv[i], dest); cdio_realpath (argv[i], dest);
printf("%s -> %s\n", argv[i], dest); printf("%s -> %s\n", argv[i], dest);
} }
exit(0); 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); calloc(1, sizeof(iso9660_stat_t)+i_rr_fname+2);
if (!p_stat_new) 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; return NULL;
} }
memcpy(p_stat_new, p_stat, stat_len); 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_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
freebsd_CFLAGS = -DTEST_DIR=\"$(srcdir)\" freebsd_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
follow_symlink_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV) realpath_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
follow_symlink_CFLAGS = -DTEST_DIR=\"$(srcdir)\" realpath_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
gnu_linux_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV) gnu_linux_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
gnu_linux_CFLAGS = -DTEST_DIR=\"$(srcdir)\" gnu_linux_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
@@ -36,7 +36,7 @@ solaris_CFLAGS = -DTEST_DIR=\"$(srcdir)\"
win32_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV) win32_LDADD = $(LIBCDIO_LIBS) $(LTLIBICONV)
win32_CFLAGS = -DTEST_DIR=\"$(srcdir)\" 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) TESTS = $(check_PROGRAMS)

View File

@@ -121,9 +121,9 @@ main(int argc, const char *argv[])
if (0 == rc) { if (0 == rc) {
/* Just when you thought we'd forgotten, here is our first /* Just when you thought we'd forgotten, here is our first
test! */ 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)) { 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); psz_file_check, psz_orig_file);
exit(1); exit(1);
} }
@@ -134,9 +134,9 @@ main(int argc, const char *argv[])
rc = check_rc(symlink(psz_symlink_file, psz_symlink_file), rc = check_rc(symlink(psz_symlink_file, psz_symlink_file),
"symlink", psz_symlink_file); "symlink", psz_symlink_file);
if (0 == rc) { 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)) { 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); psz_file_check, psz_orig_file);
exit(2); exit(2);
} }