diff --git a/configure.ac b/configure.ac index 70d25565..10c48740 100644 --- a/configure.ac +++ b/configure.ac @@ -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, diff --git a/include/cdio/util.h b/include/cdio/util.h index 81557dc7..1e653dfe 100644 --- a/include/cdio/util.h +++ b/include/cdio/util.h @@ -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 + Copyright (C) 2004, 2005, 2006, 2008, 2010 Rocky Bernstein Copyright (C) 2000 Herbert Valerio Riedel 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 +#include #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 } diff --git a/lib/driver/Makefile.am b/lib/driver/Makefile.am index b6e24dae..3b8ebc6b 100644 --- a/lib/driver/Makefile.am +++ b/lib/driver/Makefile.am @@ -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 # # 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 \ diff --git a/lib/driver/_cdio_generic.c b/lib/driver/_cdio_generic.c index e70bc24e..215f3715 100644 --- a/lib/driver/_cdio_generic.c +++ b/lib/driver/_cdio_generic.c @@ -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; } diff --git a/lib/driver/gnu_linux.c b/lib/driver/gnu_linux.c index aeb8ce94..fce8117f 100644 --- a/lib/driver/gnu_linux.c +++ b/lib/driver/gnu_linux.c @@ -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); diff --git a/lib/driver/follow_symlink.c b/lib/driver/realpath.c similarity index 76% rename from lib/driver/follow_symlink.c rename to lib/driver/realpath.c index 75cd4bc8..f3042608 100644 --- a/lib/driver/follow_symlink.c +++ b/lib/driver/realpath.c @@ -18,15 +18,15 @@ along with this program. If not, see . */ /* - 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 -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); diff --git a/lib/iso9660/iso9660_fs.c b/lib/iso9660/iso9660_fs.c index 8017729d..4b712f01 100644 --- a/lib/iso9660/iso9660_fs.c +++ b/lib/iso9660/iso9660_fs.c @@ -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); diff --git a/test/driver/Makefile.am b/test/driver/Makefile.am index 743e8add..630ca253 100644 --- a/test/driver/Makefile.am +++ b/test/driver/Makefile.am @@ -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) diff --git a/test/driver/follow_symlink.c b/test/driver/realpath.c similarity index 93% rename from test/driver/follow_symlink.c rename to test/driver/realpath.c index 9e0dd766..dfb2d51b 100644 --- a/test/driver/follow_symlink.c +++ b/test/driver/realpath.c @@ -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); }