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