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:
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user