From 69a2548913619eb81dcb6c03e27585e02fe057cd Mon Sep 17 00:00:00 2001
From: "Suren A. Chilingaryan" <csa@dside.dyndns.org>
Date: Sat, 10 Oct 2009 06:16:23 +0200
Subject: Support systems without lockf (OpenSolaris), check GTK1 headers in
 configure.in, complain on missing macros in autogen.sh, patches by Ivan
 Borzenkov and Colin Watson for eglibc compatibility

---
 .bzrignore          |   1 +
 autogen.sh          | 161 ++++++++++++++++++++++++++++++++++++++++++++++++----
 configure.in        |  25 ++++++--
 engines/Makefile.am |   2 +-
 src/rcclock.c       |  19 +++++++
 src/rccstring.h     |   8 +--
 src/rccxml.c        |  35 +++++++++++-
 7 files changed, 225 insertions(+), 26 deletions(-)

diff --git a/.bzrignore b/.bzrignore
index 86702ce..ac43524 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -32,3 +32,4 @@ ltsugar.m4
 ltversion.m4
 lt~obsolete.m4
 external/rccexternal
+stamp-h.in
diff --git a/autogen.sh b/autogen.sh
index 4c39623..e04ab90 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -4,6 +4,7 @@ PROG=`basename $0`
 
 KEYFILE=src/librcc.c
 
+
 # Some OS's have multiple versions (autoconf259, etc.) and don't have an 
 # autoconf binary
 
@@ -11,24 +12,31 @@ AUTOCONF=`which autoconf`
 if test x"${AUTOCONF}" != x -a -f "${AUTOCONF}"
 then
     AUTOCONF=autoconf
-    AUTOMAKE=automake
-    ACLOCAL=aclocal
     LIBTOOLIZE=libtoolize
     AUTOHEADER=autoheader
 else
     FINDPATH=`echo ${PATH}|sed -e 's,:, ,g'` 
     AUTOCONF=`find ${FINDPATH} -name "autoconf*"|sort -r|head -1`
-    AUTOMAKE=`find ${FINDPATH} -name "automake*"|sort -r|head -1`
-    ACLOCAL=`find ${FINDPATH} -name "aclocal*"|sort -r|head -1`
     LIBTOOLIZE=`find ${FINDPATH} -name "libtoolize*"|sort -r|head -1`
     AUTOHEADER=`find /usr/bin /usr/local/bin -name "autoheader*"|sort -r|head -1`
     echo "$0: autoconf: using ${AUTOCONF}"
-    echo "$0: automake: using ${AUTOMAKE}"
-    echo "$0: aclocal: using ${ACLOCAL}"
     echo "$0: libtoolize: using ${LIBTOOLIZE}"
     echo "$0: autoheader: using ${AUTOHEADER}"
 fi
 
+AUTOMAKE=`which automake`
+if test x"${AUTOMAKE}" != x -a -f "${AUTOMAKE}"
+then
+    AUTOMAKE=automake
+    ACLOCAL=aclocal
+else
+    FINDPATH=`echo ${PATH}|sed -e 's,:, ,g'` 
+    AUTOMAKE=`find ${FINDPATH} -name "automake*"|sort -r|head -1`
+    ACLOCAL=`find ${FINDPATH} -name "aclocal*"|sort -r|head -1`
+    echo "$0: automake: using ${AUTOMAKE}"
+    echo "$0: aclocal: using ${ACLOCAL}"
+fi
+
 GETTEXTIZE_FLAGS=--no-changelog
 AUTOPOINT_FLAGS=
 LIBTOOLIZE_FLAGS=--copy
@@ -45,12 +53,6 @@ AUTOHEADER_FLAGS=-Wall
 AUTOMAKE_FLAGS='--add-missing --copy -Wall'
 AUTOCONF_FLAGS=-Wno-obsolete
 
-die()
-{
-    err=$?
-    echo "$PROG: exited by previous error(s), return code was $err" >&2
-    exit 1
-}
 
 if [ ! -f $KEYFILE ]
 then
@@ -59,6 +61,141 @@ then
     exit 1
 fi
 
+
+boldface="`tput bold 2>/dev/null`"
+normal="`tput sgr0 2>/dev/null`"
+
+printbold() {
+    echo $ECHO_N "$boldface"
+    echo "$@"
+    echo $ECHO_N "$normal"
+}    
+
+printerr() {
+    echo "$@" >&2
+}
+
+die() {
+    err=$?
+    echo "$PROG: exited by previous error(s), return code was $err" >&2
+    exit 1
+}
+
+REQUIRED_M4MACROS=${REQUIRED_M4MACROS:-}
+FORBIDDEN_M4MACROS=${FORBIDDEN_M4MACROS:-}
+require_m4macro() {
+    case "$REQUIRED_M4MACROS" in
+	$1\ * | *\ $1\ * | *\ $1) ;;
+	*) REQUIRED_M4MACROS="$REQUIRED_M4MACROS $1" ;;
+    esac
+}
+
+forbid_m4macro() {
+    case "$FORBIDDEN_M4MACROS" in
+	$1\ * | *\ $1\ * | *\ $1) ;;
+	*) FORBIDDEN_M4MACROS="$FORBIDDEN_M4MACROS $1" ;;
+    esac
+}
+
+add_to_cm_macrodirs() {
+    case $cm_macrodirs in
+    "$1 "* | *" $1 "* | *" $1") ;;
+    *) cm_macrodirs="$cm_macrodirs $1";;
+    esac
+}
+
+check_m4macros() {
+    # construct list of macro directories
+    cm_macrodirs=`$ACLOCAL --print-ac-dir`
+    # aclocal also searches a version specific dir, eg. /usr/share/aclocal-1.9
+    # but it contains only Automake's own macros, so we can ignore it.
+
+    # Read the dirlist file, supported by Automake >= 1.7.
+    if compare_versions 1.7 $AUTOMAKE_VERSION && [ -s $cm_macrodirs/dirlist ]; then
+	cm_dirlist=`sed 's/[ 	]*#.*//;/^$/d' $cm_macrodirs/dirlist`
+	if [ -n "$cm_dirlist" ] ; then
+	    for cm_dir in $cm_dirlist; do
+		if [ -d $cm_dir ]; then
+		    add_to_cm_macrodirs $cm_dir
+		fi
+	    done
+	fi
+    fi
+
+    # Parse $ACLOCAL_FLAGS
+    set - $ACLOCAL_FLAGS
+    while [ $# -gt 0 ]; do
+	if [ "$1" = "-I" ]; then
+	    add_to_cm_macrodirs "$2"
+	    shift
+	fi
+	shift
+    done
+
+    cm_status=0
+    if [ -n "$REQUIRED_M4MACROS" ]; then
+	printbold "Checking for required M4 macros..."
+	# check that each macro file is in one of the macro dirs
+	for cm_macro in $REQUIRED_M4MACROS; do
+	    cm_macrofound=false
+	    for cm_dir in $cm_macrodirs; do
+		if [ -f "$cm_dir/$cm_macro" ]; then
+		    cm_macrofound=true
+		    break
+		fi
+		# The macro dir in Cygwin environments may contain a file
+		# called dirlist containing other directories to look in.
+		if [ -f "$cm_dir/dirlist" ]; then
+		    for cm_otherdir in `cat $cm_dir/dirlist`; do
+			if [ -f "$cm_otherdir/$cm_macro" ]; then
+			    cm_macrofound=true
+		            break
+			fi
+		    done
+		fi
+	    done
+	    if $cm_macrofound; then
+		:
+	    else
+		printerr "  $cm_macro not found"
+		cm_status=1
+	    fi
+	done
+    fi
+    if [ -n "$FORBIDDEN_M4MACROS" ]; then
+	printbold "Checking for forbidden M4 macros..."
+	# check that each macro file is in one of the macro dirs
+	for cm_macro in $FORBIDDEN_M4MACROS; do
+	    cm_macrofound=false
+	    for cm_dir in $cm_macrodirs; do
+		if [ -f "$cm_dir/$cm_macro" ]; then
+		    cm_macrofound=true
+		    break
+		fi
+	    done
+	    if $cm_macrofound; then
+		printerr "  $cm_macro found (should be cleared from macros dir)"
+		cm_status=1
+	    fi
+	done
+    fi
+    if [ "$cm_status" != 0 ]; then
+	printerr "***Error***: some autoconf macros required to build $PKG_NAME"
+	printerr "  were not found in your aclocal path, or some forbidden"
+	printerr "  macros were found.  Perhaps you need to adjust your"
+	printerr "  ACLOCAL_FLAGS?"
+	printerr
+    fi
+    return $cm_status
+}
+
+
+# PKG_CONFIG
+require_m4macro pkg.m4
+check_m4macros || die
+
+
+
 # gettextize ${GETTEXTIZE_FLAGS}
 # autopoint ${AUTOPOINT_FLAGS}
 # xml-i18n-toolize       || die
diff --git a/configure.in b/configure.in
index 4e6b9e7..a430e3c 100644
--- a/configure.in
+++ b/configure.in
@@ -28,7 +28,7 @@ AC_SUBST(LIBRCC_CVS)
 AC_SUBST(LIBRCC_CVS_DATE)
 
 AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
-
+AC_CONFIG_MACRO_DIR([m4])
 
 AC_PROG_CC
 AM_PROG_CC_C_O
@@ -54,6 +54,10 @@ AC_PATH_PROG(RM, rm, /bin/rm)
 AC_PATH_PROG(MV, mv, /bin/mv)
 AC_PATH_PROG(TAR, tar, /bin/tar)
 
+dnl Fixing ugly libtool, see for details
+dnl http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=523750
+RM="$RM -f"
+
 dnl Checks for header files.
 AC_CHECK_HEADERS(iconv.h,, [AC_MSG_ERROR(Missing iconv header)])
 AC_CHECK_HEADERS(mntent.h pwd.h sys/types.h sys/stat.h sys/file.h sys/socket.h sys/un.h sys/time.h sys/select.h sys/wait.h signal.h unistd.h fcntl.h)
@@ -81,16 +85,25 @@ dnl ***
 dnl *** GTK1 (Optional)
 dnl ***
 AC_PATH_PROG(GTK_CONFIG, gtk-config, no)
-AM_CONDITIONAL(HAVE_GTK, [ test $GTK_CONFIG != no ])
 if test $GTK_CONFIG = no; then
-    GTK1_LIBS=""
-    GTK1_INCLUDES=""
     HAVE_GTK=no
 else
     GTK1_LIBS="\`gtk-config --libs\`"
     GTK1_INCLUDES="\`gtk-config --cflags\`"
-    HAVE_GTK=yes
+    
+    saved_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS `gtk-config --cflags`"
+    AC_CHECK_HEADER([gtk/gtk.h], [HAVE_GTK=yes], [HAVE_GTK=no])
+    CFLAGS=$saved_CFLAGS
 fi
+
+AM_CONDITIONAL(HAVE_GTK, [ test $HAVE_GTK = yes ])
+
+if test $HAVE_GTK = no; then
+    GTK1_LIBS=""
+    GTK1_INCLUDES=""
+fi
+
 AC_SUBST(GTK1_LIBS)
 AC_SUBST(GTK1_INCLUDES)
 
@@ -361,7 +374,7 @@ dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 
 dnl Checks for library functions.
-AC_CHECK_FUNCS(strcasecmp strncasecmp strdup strnlen)
+AC_CHECK_FUNCS(strcasecmp strncasecmp strdup strnlen flock lockf)
 
 AC_OUTPUT(src/Makefile engines/Makefile external/Makefile ui/Makefile examples/Makefile Makefile librcc.spec)
 
diff --git a/engines/Makefile.am b/engines/Makefile.am
index 93e490a..3b8c303 100644
--- a/engines/Makefile.am
+++ b/engines/Makefile.am
@@ -1,6 +1,6 @@
 lib_LTLIBRARIES = western_engine.la
 
-libdir = $(pkgdatadir)/engines
+libdir = $(pkgdatadir)engines
 
 if HAVE_RCD
 lib_LTLIBRARIES += librcd_engine.la
diff --git a/src/rcclock.c b/src/rcclock.c
index 5683f44..b759189 100644
--- a/src/rcclock.c
+++ b/src/rcclock.c
@@ -40,6 +40,9 @@
 #ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
 #endif /* HAVE_SYS_STAT_H */
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
 
 #include "rcchome.h"
 #include "rcclock.h"
@@ -70,7 +73,14 @@ int rccLock() {
     lockfd = open(stmp, O_RDWR|O_CREAT, 0644);
     if (lockfd >= 0) {
 	for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) {
+#if defined(HAVE_FLOCK)
 	    err = flock(lockfd, LOCK_EX|LOCK_NB);
+#elif defined(HAVE_LOCKF)
+	    err = lockf(lockfd, F_TLOCK, 1);
+#else
+# warning "No file locking mechanism is detected"
+	    err = 0; // We must believe in best
+#endif
 	    if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL);
 	    else break;
 	}
@@ -85,7 +95,11 @@ int rccLock() {
 		lockfd = open(stmp, O_RDWR|O_CREAT, 0644);
 		if (lockfd >= 0) {
 		    for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) {
+#if defined(HAVE_FLOCK)
 			err = flock(lockfd, LOCK_EX|LOCK_NB);
+#elif defined(HAVE_LOCKF)
+			err = lockf(lockfd, F_TLOCK, 1);
+#endif
 			if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL);
 			else break;
 		    }
@@ -121,7 +135,12 @@ void rccUnLock() {
 
     sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir);
 
+#if defined(HAVE_FLOCK)
     flock(lockfd, LOCK_UN);
+#elif defined(HAVE_LOCKF)
+    lockf(lockfd, F_ULOCK, 1);
+#endif
+
     close(lockfd);
     lockfd = -1;
 #endif /* HAVE_SYS_FILE_H */
diff --git a/src/rccstring.h b/src/rccstring.h
index 40bda89..8bace94 100644
--- a/src/rccstring.h
+++ b/src/rccstring.h
@@ -38,13 +38,9 @@ int rccStringSetLang(rcc_string string, const char *sn);
 int rccStringFixID(rcc_string string, rcc_context ctx);
 int rccStringChangeID(rcc_string string, rcc_language_id language_id);
 
-#ifdef HAVE_STRNLEN
-# ifndef strnlen
-size_t strnlen(const char *str, size_t size);
-# endif /* !strnlen */
-#else
+#ifndef HAVE_STRNLEN
 int rccStrnlen(const char *str, size_t size);
-#endif /* HAVE_STRNLEN */
+#endif /* !HAVE_STRNLEN */
 int rccIsASCII(const char *str);
 size_t rccStringSizedGetChars(const char *str, size_t size);
 
diff --git a/src/rccxml.c b/src/rccxml.c
index 03230d0..1db5788 100644
--- a/src/rccxml.c
+++ b/src/rccxml.c
@@ -340,7 +340,12 @@ int rccSave(rcc_context ctx, const char *name) {
     sprintf(config,"%s/.rcc/%s.xml",rcc_home_dir,name);
     fd = open(config, O_CREAT|O_RDWR,00644);
     if (fd == -1) goto clear;
+
+#if defined(HAVE_FLOCK)
     flock(fd, LOCK_EX);
+#elif defined(HAVE_LOCKF)
+    lockf(fd, F_LOCK, 1);
+#endif
     
     if ((!fstat(fd, &st))&&(st.st_size)) {
 	doc = xmlReadFd(fd, config, NULL, 0);
@@ -463,7 +468,13 @@ clear:
 		xmlFreeDoc(doc);
 	    }
 	    fsync(fd);
-	    flock(fd, LOCK_UN);
+
+#if defined(HAVE_FLOCK)
+    	    flock(fd, LOCK_UN);
+#elif defined(HAVE_LOCKF)
+	    lockf(fd, F_ULOCK, 1);
+#endif
+
 	    close(fd);
 	}
 	free(config);
@@ -516,11 +527,22 @@ int rccLoad(rcc_context ctx, const char *name) {
     free(config);
 
     if (fd != -1) {
+#if defined(HAVE_FLOCK)
 	flock(fd, LOCK_EX);
+#elif defined(HAVE_LOCKF)
+	lockf(fd, F_LOCK, 1);
+#endif
+
 	if ((!fstat(fd, &st))&&(st.st_size)) {
 	    doc = xmlReadFd(fd, name, NULL, 0);
 	} 
+
+#if defined(HAVE_FLOCK)
 	flock(fd, LOCK_UN);
+#elif defined(HAVE_LOCKF)
+	lockf(fd, F_ULOCK, 1);
+#endif
+
 	close(fd);
     
 	if (doc) {
@@ -533,11 +555,22 @@ int rccLoad(rcc_context ctx, const char *name) {
     }
 
     if (sysfd != -1) {
+#if defined(HAVE_FLOCK)
 	flock(sysfd, LOCK_EX);
+#elif defined(HAVE_LOCKF)
+	lockf(sysfd, F_LOCK, 1);
+#endif
+
 	if ((!fstat(sysfd, &st))&&(st.st_size)) {
 	    sysdoc = xmlReadFd(sysfd, name, NULL, 0);
 	} 
+
+#if defined(HAVE_FLOCK)
 	flock(sysfd, LOCK_UN);
+#elif defined(HAVE_LOCKF)
+	lockf(sysfd, F_ULOCK, 1);
+#endif
+
 	close(sysfd);
     
 	if (sysdoc) {
-- 
cgit v1.2.3