summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>1998-07-13 04:17:11 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>1998-07-13 04:17:11 +0000
commit2e4a4b44ca8bb642d9fb8de6ebc439af70e32232 (patch)
treea65efecd1306744f4f6cd3a9c9e52a49caef5a1b
parente2bcc6210074ac7544c49711a659c9266d2a2d09 (diff)
Integrate local changes
-rw-r--r--gnu/usr.bin/cvs/configure165
-rw-r--r--gnu/usr.bin/cvs/configure.in23
-rw-r--r--gnu/usr.bin/cvs/src/checkout.c88
-rw-r--r--gnu/usr.bin/cvs/src/commit.c183
-rw-r--r--gnu/usr.bin/cvs/src/cvs.h5
-rw-r--r--gnu/usr.bin/cvs/src/main.c27
-rw-r--r--gnu/usr.bin/cvs/src/rcs.c931
-rw-r--r--gnu/usr.bin/cvs/src/server.c66
-rw-r--r--gnu/usr.bin/cvs/src/update.c31
9 files changed, 1163 insertions, 356 deletions
diff --git a/gnu/usr.bin/cvs/configure b/gnu/usr.bin/cvs/configure
index dd3ce3fc14d..4252a71fa98 100644
--- a/gnu/usr.bin/cvs/configure
+++ b/gnu/usr.bin/cvs/configure
@@ -2225,13 +2225,8 @@ EOF
fi
-echo $ac_n "checking for evidence of shadow passwords""... $ac_c" 1>&6
-echo "configure:2230: checking for evidence of shadow passwords" >&5
-if test -f /etc/shadow \
- || test -f /etc/security/passwd.adjunct ; then
- found="yes"
- echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6
-echo "configure:2235: checking for getspnam in -lsec" >&5
+echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6
+echo "configure:2230: checking for getspnam in -lsec" >&5
ac_lib_var=`echo sec'_'getspnam | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2239,7 +2234,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2243 "configure"
+#line 2238 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2250,7 +2245,7 @@ int main() {
getspnam()
; return 0; }
EOF
-if { (eval echo configure:2254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2249: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2277,15 +2272,15 @@ else
echo "$ac_t""no" 1>&6
fi
- for ac_func in getspnam
+for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2284: checking for $ac_func" >&5
+echo "configure:2279: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2289 "configure"
+#line 2284 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2308,7 +2303,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -2332,13 +2327,9 @@ else
fi
done
-else
- found="no"
-fi
-echo "$ac_t""$found" 1>&6
echo $ac_n "checking whether utime accepts a null argument""... $ac_c" 1>&6
-echo "configure:2342: checking whether utime accepts a null argument" >&5
+echo "configure:2333: checking whether utime accepts a null argument" >&5
if eval "test \"`echo '$''{'ac_cv_func_utime_null'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2348,7 +2339,7 @@ if test "$cross_compiling" = yes; then
ac_cv_func_utime_null=no
else
cat > conftest.$ac_ext <<EOF
-#line 2352 "configure"
+#line 2343 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -2359,7 +2350,7 @@ exit(!(stat ("conftestdata", &s) == 0 && utime("conftestdata", (long *)0) == 0
&& t.st_mtime - s.st_mtime < 120));
}
EOF
-if { (eval echo configure:2363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2354: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
then
ac_cv_func_utime_null=yes
else
@@ -2383,7 +2374,7 @@ EOF
fi
echo $ac_n "checking for long file names""... $ac_c" 1>&6
-echo "configure:2387: checking for long file names" >&5
+echo "configure:2378: checking for long file names" >&5
if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2428,7 +2419,7 @@ fi
echo $ac_n "checking for working fnmatch function""... $ac_c" 1>&6
-echo "configure:2432: checking for working fnmatch function" >&5
+echo "configure:2423: checking for working fnmatch function" >&5
if eval "test \"`echo '$''{'ccvs_cv_sys_working_fnmatch'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2436,7 +2427,7 @@ else
ccvs_cv_sys_working_fnmatch=no
else
cat > conftest.$ac_ext <<EOF
-#line 2440 "configure"
+#line 2431 "configure"
#include "confdefs.h"
#include <fnmatch.h>
@@ -2448,7 +2439,7 @@ main ()
? 0 : 1);
}
EOF
-if { (eval echo configure:2452: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
then
ccvs_cv_sys_working_fnmatch=yes
else
@@ -2473,12 +2464,12 @@ echo "$ac_t""$ccvs_cv_sys_working_fnmatch" 1>&6
# only looks in /etc/hosts), so we only look for -lsocket if we need
# it.
echo $ac_n "checking for connect""... $ac_c" 1>&6
-echo "configure:2477: checking for connect" >&5
+echo "configure:2468: checking for connect" >&5
if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2482 "configure"
+#line 2473 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char connect(); below. */
@@ -2501,7 +2492,7 @@ connect();
; return 0; }
EOF
-if { (eval echo configure:2505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_connect=yes"
else
@@ -2521,7 +2512,7 @@ else
case "$LIBS" in
*-lnsl*) ;;
*) echo $ac_n "checking for printf in -lnsl_s""... $ac_c" 1>&6
-echo "configure:2525: checking for printf in -lnsl_s" >&5
+echo "configure:2516: checking for printf in -lnsl_s" >&5
ac_lib_var=`echo nsl_s'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2529,7 +2520,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl_s $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2533 "configure"
+#line 2524 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2540,7 +2531,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2571,7 +2562,7 @@ esac
case "$LIBS" in
*-lnsl*) ;;
*) echo $ac_n "checking for printf in -lnsl""... $ac_c" 1>&6
-echo "configure:2575: checking for printf in -lnsl" >&5
+echo "configure:2566: checking for printf in -lnsl" >&5
ac_lib_var=`echo nsl'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2579,7 +2570,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2583 "configure"
+#line 2574 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2590,7 +2581,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2585: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2621,7 +2612,7 @@ esac
case "$LIBS" in
*-lsocket*) ;;
*) echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:2625: checking for connect in -lsocket" >&5
+echo "configure:2616: checking for connect in -lsocket" >&5
ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2629,7 +2620,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2633 "configure"
+#line 2624 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2640,7 +2631,7 @@ int main() {
connect()
; return 0; }
EOF
-if { (eval echo configure:2644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2671,7 +2662,7 @@ esac
case "$LIBS" in
*-linet*) ;;
*) echo $ac_n "checking for connect in -linet""... $ac_c" 1>&6
-echo "configure:2675: checking for connect in -linet" >&5
+echo "configure:2666: checking for connect in -linet" >&5
ac_lib_var=`echo inet'_'connect | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2679,7 +2670,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-linet $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2683 "configure"
+#line 2674 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2690,7 +2681,7 @@ int main() {
connect()
; return 0; }
EOF
-if { (eval echo configure:2694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2740,19 +2731,19 @@ echo "default place for krb4 is $KRB4"
krb_h=
echo $ac_n "checking for krb.h""... $ac_c" 1>&6
-echo "configure:2744: checking for krb.h" >&5
+echo "configure:2735: checking for krb.h" >&5
if test "$cross_compiling" != yes && test -r $KRB4/include/krb.h; then
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -I$KRB4/include"
cat > conftest.$ac_ext <<EOF
-#line 2749 "configure"
+#line 2740 "configure"
#include "confdefs.h"
#include <krb.h>
int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2756: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
krb_h=yes krb_incdir=$KRB4/include
else
@@ -2761,14 +2752,14 @@ else
rm -rf conftest*
CFLAGS=$hold_cflags
cat > conftest.$ac_ext <<EOF
-#line 2765 "configure"
+#line 2756 "configure"
#include "confdefs.h"
#include <krb.h>
int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
krb_h=yes krb_incdir=
else
@@ -2781,14 +2772,14 @@ rm -f conftest*
CFLAGS=$hold_cflags
else
cat > conftest.$ac_ext <<EOF
-#line 2785 "configure"
+#line 2776 "configure"
#include "confdefs.h"
#include <krb.h>
int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2783: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
krb_h=yes krb_incdir=
else
@@ -2799,14 +2790,14 @@ rm -f conftest*
fi
if test -z "$krb_h"; then
cat > conftest.$ac_ext <<EOF
-#line 2803 "configure"
+#line 2794 "configure"
#include "confdefs.h"
#include <krb.h>
int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
krb_h=yes krb_incdir=
else
@@ -2817,14 +2808,14 @@ else
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -I$KRB4/include/kerberosIV"
cat > conftest.$ac_ext <<EOF
-#line 2821 "configure"
+#line 2812 "configure"
#include "confdefs.h"
#include <krb.h>
int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2828: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
krb_h=yes krb_incdir=$KRB4/include/kerberosIV
else
@@ -2847,7 +2838,7 @@ if test -n "$krb_h"; then
hold_ldflags=$LDFLAGS
LDFLAGS="-L${KRB4}/lib $LDFLAGS"
echo $ac_n "checking for printf in -lkrb""... $ac_c" 1>&6
-echo "configure:2851: checking for printf in -lkrb" >&5
+echo "configure:2842: checking for printf in -lkrb" >&5
ac_lib_var=`echo krb'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2855,7 +2846,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2859 "configure"
+#line 2850 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2866,7 +2857,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2870: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2861: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2888,7 +2879,7 @@ LDFLAGS=$hold_ldflags
# Using open here instead of printf so we don't
# get confused by the cached value for printf from above.
echo $ac_n "checking for open in -lkrb""... $ac_c" 1>&6
-echo "configure:2892: checking for open in -lkrb" >&5
+echo "configure:2883: checking for open in -lkrb" >&5
ac_lib_var=`echo krb'_'open | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2896,7 +2887,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2900 "configure"
+#line 2891 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2907,7 +2898,7 @@ int main() {
open()
; return 0; }
EOF
-if { (eval echo configure:2911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2932,7 +2923,7 @@ fi
LDFLAGS=$hold_ldflags
else
echo $ac_n "checking for printf in -lkrb""... $ac_c" 1>&6
-echo "configure:2936: checking for printf in -lkrb" >&5
+echo "configure:2927: checking for printf in -lkrb" >&5
ac_lib_var=`echo krb'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2940,7 +2931,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2944 "configure"
+#line 2935 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -2951,7 +2942,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2955: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2985,7 +2976,7 @@ EOF
hold_ldflags=$LDFLAGS
test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}"
echo $ac_n "checking for printf in -ldes""... $ac_c" 1>&6
-echo "configure:2989: checking for printf in -ldes" >&5
+echo "configure:2980: checking for printf in -ldes" >&5
ac_lib_var=`echo des'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -2993,7 +2984,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldes $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2997 "configure"
+#line 2988 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3004,7 +2995,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:3008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3033,12 +3024,12 @@ fi
for ac_func in krb_get_err_text
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3037: checking for $ac_func" >&5
+echo "configure:3028: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3042 "configure"
+#line 3033 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3061,7 +3052,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3065: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3056: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3097,22 +3088,22 @@ echo "default place for GSSAPI is $GSSAPI"
echo $ac_n "checking for gssapi.h""... $ac_c" 1>&6
-echo "configure:3101: checking for gssapi.h" >&5
+echo "configure:3092: checking for gssapi.h" >&5
hold_cppflags=$CPPFLAGS
CPPFLAGS="$CPPFLAGS -I$GSSAPI/include "
ac_safe=`echo "gssapi/gssapi.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for gssapi/gssapi.h""... $ac_c" 1>&6
-echo "configure:3106: checking for gssapi/gssapi.h" >&5
+echo "configure:3097: checking for gssapi/gssapi.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3111 "configure"
+#line 3102 "configure"
#include "confdefs.h"
#include <gssapi/gssapi.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3116: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3107: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -3137,7 +3128,7 @@ EOF
# This is necessary on Irix 5.3, in order to link against libkrb5 --
# there, an_to_ln.o refers to things defined only in -lgen.
echo $ac_n "checking for compile in -lgen""... $ac_c" 1>&6
-echo "configure:3141: checking for compile in -lgen" >&5
+echo "configure:3132: checking for compile in -lgen" >&5
ac_lib_var=`echo gen'_'compile | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3145,7 +3136,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lgen $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3149 "configure"
+#line 3140 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3156,7 +3147,7 @@ int main() {
compile()
; return 0; }
EOF
-if { (eval echo configure:3160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3151: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3209,12 +3200,12 @@ EOF
fi
echo $ac_n "checking for gethostname""... $ac_c" 1>&6
-echo "configure:3213: checking for gethostname" >&5
+echo "configure:3204: checking for gethostname" >&5
if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3218 "configure"
+#line 3209 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostname(); below. */
@@ -3237,7 +3228,7 @@ gethostname();
; return 0; }
EOF
-if { (eval echo configure:3241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_gethostname=yes"
else
@@ -3316,12 +3307,12 @@ if test "$enable_server" = yes; then
for ac_func in crypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3320: checking for $ac_func" >&5
+echo "configure:3311: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3325 "configure"
+#line 3316 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3344,7 +3335,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3348: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3370,7 +3361,7 @@ done
if test "$ac_cv_func_crypt" = no; then
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:3374: checking for crypt in -lcrypt" >&5
+echo "configure:3365: checking for crypt in -lcrypt" >&5
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3378,7 +3369,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3382 "configure"
+#line 3373 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3389,7 +3380,7 @@ int main() {
crypt()
; return 0; }
EOF
-if { (eval echo configure:3393: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3419,12 +3410,12 @@ fi
for ac_func in crypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3423: checking for $ac_func" >&5
+echo "configure:3414: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3428 "configure"
+#line 3419 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3447,7 +3438,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3487,19 +3478,19 @@ EOF
echo $ac_n "checking for cygwin32""... $ac_c" 1>&6
-echo "configure:3491: checking for cygwin32" >&5
+echo "configure:3482: checking for cygwin32" >&5
if eval "test \"`echo '$''{'ccvs_cv_sys_cygwin32'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3496 "configure"
+#line 3487 "configure"
#include "confdefs.h"
int main() {
return __CYGWIN32__;
; return 0; }
EOF
-if { (eval echo configure:3503: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3494: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ccvs_cv_sys_cygwin32=yes
else
diff --git a/gnu/usr.bin/cvs/configure.in b/gnu/usr.bin/cvs/configure.in
index cc678db8985..7c778843990 100644
--- a/gnu/usr.bin/cvs/configure.in
+++ b/gnu/usr.bin/cvs/configure.in
@@ -91,24 +91,13 @@ AC_FUNC_VFORK
AC_FUNC_CLOSEDIR_VOID
dnl
-dnl Look for shadow password files before we go ahead and set getspnam.
-dnl On some systems (Linux), the C library has getspnam but shadow
-dnl passwords might not be in use.
+dnl Check for shadow password support.
dnl
-dnl We used to check for the existence of the /etc/security directory
-dnl here, but that's incorrect, since it's possible to have PAM installed
-dnl without using shadow passwords.
-dnl
-AC_MSG_CHECKING([for evidence of shadow passwords])
-if test -f /etc/shadow \
- || test -f /etc/security/passwd.adjunct ; then
- found="yes"
- AC_CHECK_LIB(sec, getspnam)
- AC_CHECK_FUNCS(getspnam)
-else
- found="no"
-fi
-AC_MSG_RESULT([$found])
+dnl We used to try to determine whether shadow passwords were actually in
+dnl use or not, but the code has been changed to work right reguardless,
+dnl so we can go back to a simple check.
+AC_CHECK_LIB(sec, getspnam)
+AC_CHECK_FUNCS(getspnam)
dnl We always use CVS's regular expression matcher.
dnl This is because:
diff --git a/gnu/usr.bin/cvs/src/checkout.c b/gnu/usr.bin/cvs/src/checkout.c
index 46151eb9969..c866abf8bb3 100644
--- a/gnu/usr.bin/cvs/src/checkout.c
+++ b/gnu/usr.bin/cvs/src/checkout.c
@@ -242,6 +242,13 @@ checkout (argc, argv)
error (1, 0, "tag `%s' must be a symbolic tag", tag);
}
+#ifdef SERVER_SUPPORT
+ if (server_active && where != NULL)
+ {
+ server_pathname_check (where);
+ }
+#endif
+
if (!safe_location()) {
error(1, 0, "Cannot check out files into the repository itself");
}
@@ -428,11 +435,15 @@ struct dir_to_build
/* The path to the directory. */
char *dirpath;
+ /* If set, don't build the directory, just change to it.
+ The caller will also want to set REPOSITORY to NULL. */
+ int just_chdir;
+
struct dir_to_build *next;
};
static int build_dirs_and_chdir PROTO ((struct dir_to_build *list,
- int sticky, int check_existing_dirs));
+ int sticky));
static void build_one_dir PROTO ((char *, char *, int));
@@ -723,6 +734,7 @@ internal error: %s doesn't start with %s in checkout_proc",
head->repository = NULL;
head->dirpath = xstrdup (where);
head->next = NULL;
+ head->just_chdir = 0;
/* Make a copy of the repository name to play with. */
@@ -760,7 +772,26 @@ internal error: %s doesn't start with %s in checkout_proc",
assert (strlen (where));
strcpy (new->dirpath, "/");
}
-
+ new->next = head;
+ head = new;
+
+ /* If where consists of multiple pathname components,
+ then we want to just cd into it, without creating
+ directories or modifying CVS directories as we go.
+ In CVS 1.9 and earlier, the code actually does a
+ CVS_CHDIR up-front; I'm not going to try to go back
+ to that exact code but this is somewhat similar
+ in spirit. */
+ if (where_orig != NULL
+ && cp - where < strlen (where_orig))
+ {
+ new->repository = NULL;
+ new->just_chdir = 1;
+ continue;
+ }
+
+ new->just_chdir = 0;
+
/* Now figure out what repository directory to generate.
The most complete case would be something like this:
@@ -771,12 +802,13 @@ internal error: %s doesn't start with %s in checkout_proc",
cvs co -d what/ever -N foo
The results in the CVS/Repository files should be:
- . -> . (this is where we executed the cmd)
- what -> Emptydir (generated dir -- not in repos)
+ . -> (don't touch CVS/Repository)
+ (I think this case might be buggy currently)
+ what -> (don't touch CVS/Repository)
ever -> . (same as "cd what/ever; cvs co -N foo")
bar -> Emptydir (generated dir -- not in repos)
baz -> quux (finally!) */
-
+
if (strcmp (reposcopy, CVSroot_directory) == 0)
{
/* We can't walk up past CVSROOT. Instead, the
@@ -835,9 +867,6 @@ internal error: %s doesn't start with %s in checkout_proc",
}
}
}
-
- new->next = head;
- head = new;
}
/* clean up */
@@ -852,7 +881,11 @@ internal error: %s doesn't start with %s in checkout_proc",
may not have a thing to do with where the sources are
being checked out. If it does, build_dirs_and_chdir
will take care of creating adm files here. */
-
+ /* FIXME: checking where_is_absolute is a horrid kludge;
+ I suspect we probably can just skip the call to
+ build_one_dir whenever the -d command option was specified
+ to checkout. */
+
if (! where_is_absolute)
{
/* It may be argued that we shouldn't set any sticky
@@ -866,8 +899,7 @@ internal error: %s doesn't start with %s in checkout_proc",
contain a CVS subdir yet, but all the others contain
CVS and Entries.Static files */
- if (build_dirs_and_chdir (head, *pargc <= 1,
- where_is_absolute) != 0)
+ if (build_dirs_and_chdir (head, *pargc <= 1) != 0)
{
error (0, 0, "ignoring module %s", omodule);
err = 1;
@@ -1101,22 +1133,13 @@ emptydir_name ()
return repository;
}
-
-/* Build all the dirs along the path to DIRS with CVS subdirs with
- appropriate repositories. If ->repository is NULL, do not create a
- CVSADM directory for that subdirectory; just CVS_CHDIR into it. If
- check_existing_dirs is nonzero, don't create directories if they
- already exist, and don't try to write adm files in directories
- where we don't have write permission. We use this last option
- primarily when a user has specified an absolute path for checkout
- -- we will often not have permission to top-level directories, so
- we shouldn't complain. */
-
+/* Build all the dirs along the path to DIRS with CVS subdirs with appropriate
+ repositories. If ->repository is NULL, do not create a CVSADM directory
+ for that subdirectory; just CVS_CHDIR into it. */
static int
-build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
+build_dirs_and_chdir (dirs, sticky)
struct dir_to_build *dirs;
int sticky;
- int check_existing_dirs;
{
int retval = 0;
struct dir_to_build *nextdir;
@@ -1124,16 +1147,12 @@ build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
while (dirs != NULL)
{
char *dir = last_component (dirs->dirpath);
- int dir_is_writeable;
- if ((! check_existing_dirs) || (! isdir (dir)))
+ if (!dirs->just_chdir)
+ {
mkdir_if_needed (dir);
-
- Subdir_Register (NULL, NULL, dir);
-
- /* This is an expensive call -- only make it if necessary. */
- if (check_existing_dirs)
- dir_is_writeable = iswritable (dir);
+ Subdir_Register (NULL, NULL, dir);
+ }
if (CVS_CHDIR (dir) < 0)
{
@@ -1141,14 +1160,11 @@ build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
retval = 1;
goto out;
}
-
- if ((dirs->repository != NULL)
- && ((! check_existing_dirs) || dir_is_writeable))
+ if (dirs->repository != NULL)
{
build_one_dir (dirs->repository, dirs->dirpath, sticky);
free (dirs->repository);
}
-
nextdir = dirs->next;
free (dirs->dirpath);
free (dirs);
diff --git a/gnu/usr.bin/cvs/src/commit.c b/gnu/usr.bin/cvs/src/commit.c
index 4aa243868a9..2201407a7d3 100644
--- a/gnu/usr.bin/cvs/src/commit.c
+++ b/gnu/usr.bin/cvs/src/commit.c
@@ -1,17 +1,17 @@
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
- *
+ *
* You may distribute under the terms of the GNU General Public License as
* specified in the README file that comes with the CVS source distribution.
- *
+ *
* Commit Files
- *
+ *
* "commit" commits the present version to the RCS repository, AFTER
* having done a test on conflicts.
*
* The call is: cvs commit [options] files...
- *
+ *
*/
#include <assert.h>
@@ -29,7 +29,7 @@ static int check_filesdoneproc PROTO ((void *callerdat, int err,
char *repos, char *update_dir,
List *entries));
static int checkaddfile PROTO((char *file, char *repository, char *tag,
- char *options, RCSNode **rcsnode));
+ char *options, RCSNode **rcsnode));
static Dtype commit_direntproc PROTO ((void *callerdat, char *dir,
char *repos, char *update_dir,
List *entries));
@@ -74,12 +74,13 @@ static int force_ci = 0;
static int got_message;
static int run_module_prog = 1;
static int aflag;
-static char *tag;
+static char *saved_tag;
static char *write_dirtag;
static int write_dirnonbranch;
static char *logfile;
static List *mulist;
-static char *message;
+static List *saved_ulist;
+static char *saved_message;
static time_t last_register_time;
static const char *const commit_usage[] =
@@ -247,7 +248,7 @@ find_fileproc (callerdat, finfo)
xfinfo.repository = NULL;
xfinfo.rcs = NULL;
- vers = Version_TS (&xfinfo, NULL, tag, NULL, 0, 0);
+ vers = Version_TS (&xfinfo, NULL, saved_tag, NULL, 0, 0);
if (vers->ts_user == NULL
&& vers->vn_user != NULL
&& vers->vn_user[0] == '-')
@@ -364,18 +365,18 @@ commit (argc, argv)
#else
use_editor = 0;
#endif
- if (message)
+ if (saved_message)
{
- free (message);
- message = NULL;
+ free (saved_message);
+ saved_message = NULL;
}
- message = xstrdup(optarg);
+ saved_message = xstrdup(optarg);
break;
case 'r':
- if (tag)
- free (tag);
- tag = xstrdup (optarg);
+ if (saved_tag)
+ free (saved_tag);
+ saved_tag = xstrdup (optarg);
break;
case 'l':
local = 1;
@@ -405,12 +406,12 @@ commit (argc, argv)
argv += optind;
/* numeric specified revision means we ignore sticky tags... */
- if (tag && isdigit (*tag))
+ if (saved_tag && isdigit (*saved_tag))
{
aflag = 1;
/* strip trailing dots */
- while (tag[strlen (tag) - 1] == '.')
- tag[strlen (tag) - 1] = '\0';
+ while (saved_tag[strlen (saved_tag) - 1] == '.')
+ saved_tag[strlen (saved_tag) - 1] = '\0';
}
/* some checks related to the "-F logfile" option */
@@ -419,7 +420,7 @@ commit (argc, argv)
int n, logfd;
struct stat statbuf;
- if (message)
+ if (saved_message)
error (1, 0, "cannot specify both a message and a log file");
/* FIXME: Why is this binary? Needs more investigation. */
@@ -429,21 +430,20 @@ commit (argc, argv)
if (fstat(logfd, &statbuf) < 0)
error (1, errno, "cannot find size of log file %s", logfile);
- message = xmalloc (statbuf.st_size + 1);
+ saved_message = xmalloc (statbuf.st_size + 1);
/* FIXME: Should keep reading until EOF, rather than assuming the
first read gets the whole thing. */
- if ((n = read (logfd, message, statbuf.st_size + 1)) < 0)
+ if ((n = read (logfd, saved_message, statbuf.st_size + 1)) < 0)
error (1, errno, "cannot read log message from %s", logfile);
(void) close (logfd);
- message[n] = '\0';
+ saved_message[n] = '\0';
}
#ifdef CLIENT_SUPPORT
- if (client_active)
+ if (client_active)
{
- int err;
struct find_data find_args;
ign_setup ();
@@ -458,7 +458,7 @@ commit (argc, argv)
I haven't really thought about it much.
Anyway, I suspect that setting it unnecessarily only causes
a little unneeded network traffic. */
- find_args.force = force_ci || tag != NULL;
+ find_args.force = force_ci || saved_tag != NULL;
err = start_recursion (find_fileproc, find_filesdoneproc,
find_dirent_proc, (DIRLEAVEPROC) NULL,
@@ -500,17 +500,17 @@ commit (argc, argv)
* The protocol is designed this way. This is a feature.
*/
if (use_editor)
- do_editor (".", &message, (char *)NULL, find_args.ulist);
+ do_editor (".", &saved_message, (char *)NULL, find_args.ulist);
/* Run the user-defined script to verify/check information in
*the log message
*/
- do_verify (message, (char *)NULL);
+ do_verify (saved_message, (char *)NULL);
/* We always send some sort of message, even if empty. */
/* FIXME: is that true? There seems to be some code in do_editor
which can leave the message NULL. */
- option_with_arg ("-m", message);
+ option_with_arg ("-m", saved_message);
/* OK, now process all the questionable files we have been saving
up. */
@@ -559,7 +559,7 @@ commit (argc, argv)
send_arg("-f");
if (!run_module_prog)
send_arg("-n");
- option_with_arg ("-r", tag);
+ option_with_arg ("-r", saved_tag);
/* Sending only the names of the files which were modified, added,
or removed means that the server will only do an up-to-date
@@ -582,7 +582,7 @@ commit (argc, argv)
send_to_server ("ci\012", 0);
err = get_responses_and_close ();
- if (err != 0 && use_editor && message != NULL)
+ if (err != 0 && use_editor && saved_message != NULL)
{
/* If there was an error, don't nuke the user's carefully
constructed prose. This is something of a kludge; a better
@@ -600,7 +600,8 @@ commit (argc, argv)
fp = CVS_FOPEN (fname, "w+");
if (fp == NULL)
error (1, 0, "cannot create temporary file %s", fname);
- if (fwrite (message, 1, strlen (message), fp) != strlen (message))
+ if (fwrite (saved_message, 1, strlen (saved_message), fp)
+ != strlen (saved_message))
error (1, errno, "cannot write temporary file %s", fname);
if (fclose (fp) < 0)
error (0, errno, "cannot close temporary file %s", fname);
@@ -610,12 +611,12 @@ commit (argc, argv)
}
#endif
- if (tag != NULL)
- tag_check_valid (tag, argc, argv, local, aflag, "");
+ if (saved_tag != NULL)
+ tag_check_valid (saved_tag, argc, argv, local, aflag, "");
/* XXX - this is not the perfect check for this */
if (argc <= 0)
- write_dirtag = tag;
+ write_dirtag = saved_tag;
wrap_setup ();
@@ -651,17 +652,6 @@ commit (argc, argv)
error (1, 0, "correct above errors first!");
}
-#ifdef PRESERVE_PERMISSIONS_SUPPORT
- if (preserve_perms)
- {
- /* hardlist now includes a complete index of the files
- to be committed, indexed by inode. For each inode,
- compile a list of the files that are linked to it,
- and save this list in each file's hardlink_info node. */
- (void) walklist (hardlist, cache_hardlinks_proc, NULL);
- }
-#endif
-
/*
* Run the recursion processor to commit the files
*/
@@ -683,7 +673,7 @@ commit (argc, argv)
time_t now;
(void) time (&now);
- if (now == last_register_time)
+ if (now == last_register_time)
{
sleep (1); /* to avoid time-stamp races */
}
@@ -713,10 +703,10 @@ classify_file_internal (finfo, vers)
noexec = quiet = really_quiet = 1;
/* handle specified numeric revision specially */
- if (tag && isdigit (*tag))
+ if (saved_tag && isdigit (*saved_tag))
{
/* If the tag is for the trunk, make sure we're at the head */
- if (numdots (tag) < 2)
+ if (numdots (saved_tag) < 2)
{
status = Classify_File (finfo, (char *) NULL, (char *) NULL,
(char *) NULL, 1, aflag, vers, 0);
@@ -726,7 +716,7 @@ classify_file_internal (finfo, vers)
Ctype xstatus;
freevers_ts (vers);
- xstatus = Classify_File (finfo, tag, (char *) NULL,
+ xstatus = Classify_File (finfo, saved_tag, (char *) NULL,
(char *) NULL, 1, aflag, vers, 0);
if (xstatus == T_REMOVE_ENTRY)
status = T_MODIFIED;
@@ -744,7 +734,7 @@ classify_file_internal (finfo, vers)
* The revision is off the main trunk; make sure we're
* up-to-date with the head of the specified branch.
*/
- xtag = xstrdup (tag);
+ xtag = xstrdup (saved_tag);
if ((numdots (xtag) & 1) != 0)
{
cp = strrchr (xtag, '.');
@@ -765,12 +755,12 @@ classify_file_internal (finfo, vers)
}
/* now, muck with vers to make the tag correct */
free ((*vers)->tag);
- (*vers)->tag = xstrdup (tag);
+ (*vers)->tag = xstrdup (saved_tag);
free (xtag);
}
}
else
- status = Classify_File (finfo, tag, (char *) NULL, (char *) NULL,
+ status = Classify_File (finfo, saved_tag, (char *) NULL, (char *) NULL,
1, 0, vers, 0);
noexec = save_noexec;
quiet = save_quiet;
@@ -796,7 +786,7 @@ check_fileproc (callerdat, finfo)
Vers_TS *vers;
struct commit_info *ci;
struct logfile_info *li;
-
+
status = classify_file_internal (finfo, &vers);
/*
@@ -835,7 +825,7 @@ check_fileproc (callerdat, finfo)
* allow the commit if timestamp is identical or if we find
* an RCS_MERGE_PAT in the file.
*/
- if (!tag || !isdigit (*tag))
+ if (!saved_tag || !isdigit (*saved_tag))
{
if (vers->date)
{
@@ -1047,7 +1037,6 @@ warning: file `%s' seems to still contain conflict indicators",
hlinfo = (struct hardlink_info *)
xmalloc (sizeof (struct hardlink_info));
hlinfo->status = status;
- hlinfo->links = NULL;
linkp->data = (char *) hlinfo;
}
}
@@ -1114,7 +1103,6 @@ precommit_list_proc (p, closure)
/*
* Callback proc for pre-commit checking
*/
-static List *ulist;
static int
precommit_proc (repository, filter)
char *repository;
@@ -1124,7 +1112,7 @@ precommit_proc (repository, filter)
if (isabsolute (filter))
{
char *s, *cp;
-
+
s = xstrdup (filter);
for (cp = s; *cp; cp++)
if (isspace (*cp))
@@ -1143,7 +1131,7 @@ precommit_proc (repository, filter)
run_setup (filter);
run_arg (repository);
- (void) walklist (ulist, precommit_list_proc, NULL);
+ (void) walklist (saved_ulist, precommit_list_proc, NULL);
return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
}
@@ -1165,12 +1153,12 @@ check_filesdoneproc (callerdat, err, repos, update_dir, entries)
/* find the update list for this dir */
p = findnode (mulist, update_dir);
if (p != NULL)
- ulist = ((struct master_lists *) p->data)->ulist;
+ saved_ulist = ((struct master_lists *) p->data)->ulist;
else
- ulist = (List *) NULL;
+ saved_ulist = (List *) NULL;
/* skip the checks if there's nothing to do */
- if (ulist == NULL || ulist->list->next == ulist->list)
+ if (saved_ulist == NULL || saved_ulist->list->next == saved_ulist->list)
return (err);
/* run any pre-commit checks */
@@ -1238,8 +1226,9 @@ commit_fileproc (callerdat, finfo)
{
got_message = 1;
if (use_editor)
- do_editor (finfo->update_dir, &message, finfo->repository, ulist);
- do_verify (message, finfo->repository);
+ do_editor (finfo->update_dir, &saved_message,
+ finfo->repository, ulist);
+ do_verify (saved_message, finfo->repository);
}
p = findnode (cilist, finfo->file);
@@ -1279,7 +1268,7 @@ commit_fileproc (callerdat, finfo)
error (1, 0, "internal error: no parsed RCS file");
ci->rev = RCS_whatbranch (finfo->rcs, ci->tag);
err = Checkin ('A', finfo, finfo->rcs->path, ci->rev,
- ci->tag, ci->options, message);
+ ci->tag, ci->options, saved_message);
if (err != 0)
{
unlockrcs (finfo->rcs);
@@ -1319,7 +1308,7 @@ commit_fileproc (callerdat, finfo)
{
err = Checkin ('M', finfo,
finfo->rcs->path, ci->rev, ci->tag,
- ci->options, message);
+ ci->options, saved_message);
(void) time (&last_register_time);
@@ -1331,7 +1320,7 @@ commit_fileproc (callerdat, finfo)
}
else if (ci->status == T_REMOVED)
{
- err = remove_file (finfo, ci->tag, message);
+ err = remove_file (finfo, ci->tag, saved_message);
#ifdef SERVER_SUPPORT
if (server_active) {
server_scratch_entry_only ();
@@ -1371,7 +1360,7 @@ out:
been removed from the archive, which is not the behavior we
want for our commitlog messages; we want the old version
number and then "NONE." */
-
+
if (ci->status != T_REMOVED)
{
p = findnode (ulist, finfo->file);
@@ -1379,7 +1368,7 @@ out:
{
Vers_TS *vers;
struct logfile_info *li;
-
+
(void) classify_file_internal (finfo, &vers);
li = (struct logfile_info *) p->data;
li->rev_new = xstrdup (vers->vn_rcs);
@@ -1415,7 +1404,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
got_message = 0;
- Update_Logfile (repository, message, (FILE *) 0, ulist);
+ Update_Logfile (repository, saved_message, (FILE *) 0, ulist);
/* Build the administrative files if necessary. */
{
@@ -1423,11 +1412,17 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
if (strncmp (CVSroot_directory, repository,
strlen (CVSroot_directory)) != 0)
- error (0, 0, "internal error: repository (%s) doesn't begin with root (%s)", repository, CVSroot_directory);
+ error (0, 0,
+ "internal error: repository (%s) doesn't begin with root (%s)",
+ repository, CVSroot_directory);
p = repository + strlen (CVSroot_directory);
if (*p == '/')
++p;
- if (strcmp ("CVSROOT", p) == 0)
+ if (strcmp ("CVSROOT", p) == 0
+ /* Check for subdirectories because people may want to create
+ subdirectories and list files therein in checkoutlist. */
+ || strncmp ("CVSROOT/", p, strlen ("CVSROOT/")) == 0
+ )
{
/* "Database" might a little bit grandiose and/or vague,
but "checked-out copies of administrative files, unless
@@ -1435,11 +1430,20 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
case modules.{pag,dir,db}" is verbose and excessively
focused on how the database is implemented. */
+ /* mkmodules requires the absolute name of the CVSROOT directory.
+ Remove anything after the `CVSROOT' component -- this is
+ necessary when committing in a subdirectory of CVSROOT. */
+ char *admin_dir = xstrdup (repository);
+ assert (admin_dir[p - repository + strlen ("CVSROOT")] == '\0'
+ || admin_dir[p - repository + strlen ("CVSROOT")] == '/');
+ admin_dir[p - repository + strlen ("CVSROOT")] = '\0';
+
cvs_output (program_name, 0);
cvs_output (" ", 1);
cvs_output (command_name, 0);
cvs_output (": Rebuilding administrative file database\n", 0);
- mkmodules (repository);
+ mkmodules (admin_dir);
+ free (admin_dir);
}
}
@@ -1452,7 +1456,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
char *line;
int line_length;
size_t line_chars_allocated;
- char *repository;
+ char *repos;
line = NULL;
line_chars_allocated = 0;
@@ -1462,9 +1466,9 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
/* Remove any trailing newline. */
if (line[line_length - 1] == '\n')
line[--line_length] = '\0';
- repository = Name_Repository ((char *) NULL, update_dir);
+ repos = Name_Repository ((char *) NULL, update_dir);
run_setup (line);
- run_arg (repository);
+ run_arg (repos);
cvs_output (program_name, 0);
cvs_output (" ", 1);
cvs_output (command_name, 0);
@@ -1472,7 +1476,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
run_print (stdout);
cvs_output ("'\n", 0);
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
- free (repository);
+ free (repos);
}
else
{
@@ -1529,8 +1533,8 @@ commit_direntproc (callerdat, dir, repos, update_dir, entries)
real_repos = Name_Repository (dir, update_dir);
got_message = 1;
if (use_editor)
- do_editor (update_dir, &message, real_repos, ulist);
- do_verify (message, real_repos);
+ do_editor (update_dir, &saved_message, real_repos, ulist);
+ do_verify (saved_message, real_repos);
free (real_repos);
return (R_PROCESS);
}
@@ -1622,7 +1626,7 @@ remove_file (finfo, tag, message)
if (tag && !(branch = RCS_nodeisbranch (finfo->rcs, tag)))
{
/* a symbolic tag is specified; just remove the tag from the file */
- if ((retcode = RCS_deltag (finfo->rcs, tag)) != 0)
+ if ((retcode = RCS_deltag (finfo->rcs, tag)) != 0)
{
if (!quiet)
error (0, retcode == -1 ? errno : 0,
@@ -1655,7 +1659,7 @@ remove_file (finfo, tag, message)
error (0, 0, "cannot find branch \"%s\".", tag);
return (1);
}
-
+
branchname = RCS_getbranch (finfo->rcs, rev, 1);
if (branchname == NULL)
{
@@ -1676,12 +1680,12 @@ remove_file (finfo, tag, message)
/* Get current head revision of file. */
prev_rev = RCS_head (finfo->rcs);
}
-
+
/* if removing without a tag or a branch, then make sure the default
branch is the trunk. */
if (!tag && !branch)
{
- if (RCS_setbranch (finfo->rcs, NULL) != 0)
+ if (RCS_setbranch (finfo->rcs, NULL) != 0)
{
error (0, 0, "cannot change branch to default for %s",
finfo->fullname);
@@ -1740,7 +1744,7 @@ remove_file (finfo, tag, message)
if (!branch)
{
/* this was the head; really move it into the Attic */
- tmp = xmalloc(strlen(finfo->repository) +
+ tmp = xmalloc(strlen(finfo->repository) +
sizeof('/') +
sizeof(CVSATTIC) +
sizeof('/') +
@@ -1750,8 +1754,9 @@ remove_file (finfo, tag, message)
omask = umask (cvsumask);
(void) CVS_MKDIR (tmp, 0777);
(void) umask (omask);
- (void) sprintf (tmp, "%s/%s/%s%s", finfo->repository, CVSATTIC, finfo->file, RCSEXT);
-
+ (void) sprintf (tmp, "%s/%s/%s%s", finfo->repository, CVSATTIC,
+ finfo->file, RCSEXT);
+
if (strcmp (finfo->rcs->path, tmp) != 0
&& CVS_RENAME (finfo->rcs->path, tmp) == -1
&& (isreadable (finfo->rcs->path) || !isreadable (tmp)))
@@ -1794,7 +1799,7 @@ finaladd (finfo, rev, tag, options)
char *rcs;
rcs = locate_rcs (finfo->file, finfo->repository);
- ret = Checkin ('A', finfo, rcs, rev, tag, options, message);
+ ret = Checkin ('A', finfo, rcs, rev, tag, options, saved_message);
if (ret == 0)
{
char *tmp = xmalloc (strlen (finfo->file) + sizeof (CVSADM)
@@ -1931,7 +1936,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
Attic. */
oldfile = xstrdup (rcs);
sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
-
+
if (strcmp (oldfile, rcs) == 0)
{
error (0, 0, "internal error: confused about attic for %s",
@@ -2154,7 +2159,7 @@ internal error: `%s' didn't move out of the attic",
retval = 1;
goto out;
}
- }
+ }
if (rcsnode && *rcsnode != rcsfile)
{
@@ -2200,7 +2205,7 @@ lock_RCS (user, rcs, rev, repository)
* For a specified, numeric revision of the form "1" or "1.1", (or when
* no revision is specified ""), definitely move the branch to the trunk
* before locking the RCS file.
- *
+ *
* The assumption is that if there is more than one revision on the trunk,
* the head points to the trunk, not a branch... and as such, it's not
* necessary to move the head in this case.
diff --git a/gnu/usr.bin/cvs/src/cvs.h b/gnu/usr.bin/cvs/src/cvs.h
index 87f653598f3..49dbded4358 100644
--- a/gnu/usr.bin/cvs/src/cvs.h
+++ b/gnu/usr.bin/cvs/src/cvs.h
@@ -433,6 +433,8 @@ void Subdir_Register PROTO((List *, const char *, const char *));
void Subdir_Deregister PROTO((List *, const char *, const char *));
char *Make_Date PROTO((char *rawdate));
+char *date_from_time_t PROTO ((time_t));
+
char *Name_Repository PROTO((char *dir, char *update_dir));
char *Short_Repository PROTO((char *repository));
void Sanitize_Repository_Name PROTO((char *repository));
@@ -480,7 +482,6 @@ int numdots PROTO((const char *s));
char *increment_revnum PROTO ((const char *));
int compare_revnums PROTO ((const char *, const char *));
int unlink_file PROTO((const char *f));
-int link_file PROTO ((const char *from, const char *to));
int unlink_file_dir PROTO((const char *f));
int update PROTO((int argc, char *argv[]));
int xcmp PROTO((const char *file1, const char *file2));
@@ -838,7 +839,7 @@ extern int patch PROTO((int argc, char **argv));
extern int release PROTO((int argc, char **argv));
extern int cvsremove PROTO((int argc, char **argv));
extern int rtag PROTO((int argc, char **argv));
-extern int status PROTO((int argc, char **argv));
+extern int cvsstatus PROTO((int argc, char **argv));
extern int cvstag PROTO((int argc, char **argv));
extern unsigned long int lookup_command_attribute PROTO((char *));
diff --git a/gnu/usr.bin/cvs/src/main.c b/gnu/usr.bin/cvs/src/main.c
index 3f90e6973b7..d2d3824d17e 100644
--- a/gnu/usr.bin/cvs/src/main.c
+++ b/gnu/usr.bin/cvs/src/main.c
@@ -110,7 +110,7 @@ static const struct cmd
{ "rdiff", "patch", "pa", patch },
{ "release", "re", "rel", release },
{ "remove", "rm", "delete", cvsremove },
- { "status", "st", "stat", status },
+ { "status", "st", "stat", cvsstatus },
{ "rtag", "rt", "rfreeze", rtag },
{ "tag", "ta", "freeze", cvstag },
{ "unedit", NULL, NULL, unedit },
@@ -973,20 +973,37 @@ char *
Make_Date (rawdate)
char *rawdate;
{
- struct tm *ftm;
time_t unixtime;
- char date[MAXDATELEN];
- char *ret;
unixtime = get_date (rawdate, (struct timeb *) NULL);
if (unixtime == (time_t) - 1)
error (1, 0, "Can't parse date/time: %s", rawdate);
+ return date_from_time_t (unixtime);
+}
+
+/* Convert a time_t to an RCS format date. This is mainly for the
+ use of "cvs history", because the CVSROOT/history file contains
+ time_t format dates; most parts of CVS will want to avoid using
+ time_t's directly, and instead use RCS_datecmp, Make_Date, &c.
+ Assuming that the time_t is in GMT (as it generally should be),
+ then the result will be in GMT too.
+
+ Returns a newly malloc'd string. */
+
+char *
+date_from_time_t (unixtime)
+ time_t unixtime;
+{
+ struct tm *ftm;
+ char date[MAXDATELEN];
+ char *ret;
ftm = gmtime (&unixtime);
if (ftm == NULL)
/* This is a system, like VMS, where the system clock is in local
time. Hopefully using localtime here matches the "zero timezone"
- hack I added to get_date. */
+ hack I added to get_date (get_date of course being the relevant
+ issue for Make_Date, and for history.c too I think). */
ftm = localtime (&unixtime);
(void) sprintf (date, DATEFORM,
diff --git a/gnu/usr.bin/cvs/src/rcs.c b/gnu/usr.bin/cvs/src/rcs.c
index c74e5ea7e24..65fb0702f6c 100644
--- a/gnu/usr.bin/cvs/src/rcs.c
+++ b/gnu/usr.bin/cvs/src/rcs.c
@@ -81,6 +81,9 @@ static void free_rcsnode_contents PROTO((RCSNode *));
static void free_rcsvers_contents PROTO((RCSVers *));
static void rcsvers_delproc PROTO((Node * p));
static char *translate_symtag PROTO((RCSNode *, const char *));
+static char *RCS_addbranch PROTO ((RCSNode *, const char *));
+static char *truncate_revnum_in_place PROTO ((char *));
+static char *truncate_revnum PROTO ((const char *));
static char *printable_date PROTO((const char *));
static char *escape_keyword_value PROTO ((const char *, int *));
static void expand_keywords PROTO((RCSNode *, RCSVers *, const char *,
@@ -563,7 +566,9 @@ RCS_reparsercsfile (rdata, pfp, rcsbufp)
key, rcsfile);
free (rdata->desc);
}
- rdata->desc = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *) NULL);
+ /* Don't need to rcsbuf_valcopy `value' because
+ getdelta already did that. */
+ rdata->desc = xstrdup (value);
}
rdata->delta_pos = rcsbuf_ftell (&rcsbuf);
@@ -799,6 +804,9 @@ free_rcsnode_contents (rnode)
/* free_rcsvers_contents -- free up the contents of an RCSVers node,
but also free the pointer to the node itself. */
+/* Note: The `hardlinks' list is *not* freed, since it is merely a
+ pointer into the `hardlist' structure (defined in hardlink.c), and
+ that structure is freed elsewhere in the program. */
static void
free_rcsvers_contents (rnode)
@@ -1281,6 +1289,480 @@ rcsbuf_getkey (rcsbuf, keyp, valp)
#undef my_whitespace
}
+/* TODO: Eliminate redundant code in rcsbuf_getkey, rcsbuf_getid,
+ rcsbuf_getstring, rcsbuf_getword. These last three functions were
+ all created by hacking monstrous swaths of code from rcsbuf_getkey,
+ and some engineering would make the code easier to read and
+ maintain.
+
+ Note that the extreme hair in rcsbuf_getkey is because profiling
+ statistics show that it was worth it.
+
+ We probably could be processing "hardlinks" by first calling
+ rcsbuf_getkey, and breaking up the value afterwards; the code to
+ break it up would not need to be hacked for speed. This would
+ remove the need for rcsbuf_getword, rcsbuf_getid, and
+ rcsbuf_getstring, as the other calls are easy to remove. */
+
+/* Read an `id' (in the sense of rcsfile(5)) from RCSBUF, and store in
+ IDP. */
+
+static int
+rcsbuf_getid (rcsbuf, idp)
+ struct rcsbuffer *rcsbuf;
+ char **idp;
+{
+ register const char * const my_spacetab = spacetab;
+ register char *ptr, *ptrend;
+ char c;
+
+#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
+
+ rcsbuf->vlen = 0;
+ rcsbuf->at_string = 0;
+ rcsbuf->embedded_at = 0;
+
+ ptr = rcsbuf->ptr;
+ ptrend = rcsbuf->ptrend;
+
+ /* Sanity check. */
+ if (ptr < rcsbuf_buffer || ptr > rcsbuf_buffer + rcsbuf_buffer_size)
+ abort ();
+
+ /* If the pointer is more than RCSBUF_BUFSIZE bytes into the
+ buffer, move back to the start of the buffer. This keeps the
+ buffer from growing indefinitely. */
+ if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
+ {
+ int len;
+
+ len = ptrend - ptr;
+
+ /* Sanity check: we don't read more than RCSBUF_BUFSIZE bytes
+ at a time, so we can't have more bytes than that past PTR. */
+ if (len > RCSBUF_BUFSIZE)
+ abort ();
+
+ /* Update the POS field, which holds the file offset of the
+ first byte in the RCSBUF_BUFFER buffer. */
+ rcsbuf->pos += ptr - rcsbuf_buffer;
+
+ memcpy (rcsbuf_buffer, ptr, len);
+ ptr = rcsbuf_buffer;
+ ptrend = ptr + len;
+ rcsbuf->ptrend = ptrend;
+ }
+
+ /* Skip leading whitespace. */
+
+ while (1)
+ {
+ if (ptr >= ptrend)
+ {
+ ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
+ if (ptr == NULL)
+ return 0;
+ ptrend = rcsbuf->ptrend;
+ }
+
+ c = *ptr;
+ if (! my_whitespace (c))
+ break;
+
+ ++ptr;
+ }
+
+ /* We've found the start of the key. */
+
+ *idp = ptr;
+
+ if (c != ';')
+ {
+ while (1)
+ {
+ ++ptr;
+ if (ptr >= ptrend)
+ {
+ ptr = rcsbuf_fill (rcsbuf, ptr, idp, (char **) NULL);
+ if (ptr == NULL)
+ error (1, 0, "EOF in key in RCS file %s",
+ rcsbuf->filename);
+ ptrend = rcsbuf->ptrend;
+ }
+ c = *ptr;
+ if (c == ';' || my_whitespace (c))
+ break;
+ }
+ }
+
+ /* Here *IDP points to the id in the buffer, C is the character
+ we found at the end of the key, and PTR points to the location in
+ the buffer where we found C. We may not set *PTR to \0, because
+ it may overwrite a terminating semicolon. The calling function
+ must copy and terminate the id on its own. */
+
+ rcsbuf->ptr = ptr;
+ return 1;
+
+#undef my_whitespace;
+}
+
+/* Read an RCS @-delimited string. Store the result in STRP. */
+
+static int
+rcsbuf_getstring (rcsbuf, strp)
+ struct rcsbuffer *rcsbuf;
+ char **strp;
+{
+ register const char * const my_spacetab = spacetab;
+ register char *ptr, *ptrend;
+ char *pat;
+ size_t vlen;
+ char c;
+
+#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
+
+ rcsbuf->vlen = 0;
+ rcsbuf->at_string = 0;
+ rcsbuf->embedded_at = 0;
+
+ ptr = rcsbuf->ptr;
+ ptrend = rcsbuf->ptrend;
+
+ /* Sanity check. */
+ if (ptr < rcsbuf_buffer || ptr > rcsbuf_buffer + rcsbuf_buffer_size)
+ abort ();
+
+ /* If the pointer is more than RCSBUF_BUFSIZE bytes into the
+ buffer, move back to the start of the buffer. This keeps the
+ buffer from growing indefinitely. */
+ if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
+ {
+ int len;
+
+ len = ptrend - ptr;
+
+ /* Sanity check: we don't read more than RCSBUF_BUFSIZE bytes
+ at a time, so we can't have more bytes than that past PTR. */
+ if (len > RCSBUF_BUFSIZE)
+ abort ();
+
+ /* Update the POS field, which holds the file offset of the
+ first byte in the RCSBUF_BUFFER buffer. */
+ rcsbuf->pos += ptr - rcsbuf_buffer;
+
+ memcpy (rcsbuf_buffer, ptr, len);
+ ptr = rcsbuf_buffer;
+ ptrend = ptr + len;
+ rcsbuf->ptrend = ptrend;
+ }
+
+ /* Skip leading whitespace. */
+
+ while (1)
+ {
+ if (ptr >= ptrend)
+ {
+ ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
+ if (ptr == NULL)
+ error (1, 0, "unexpected end of file reading %s",
+ rcsbuf->filename);
+ ptrend = rcsbuf->ptrend;
+ }
+
+ c = *ptr;
+ if (! my_whitespace (c))
+ break;
+
+ ++ptr;
+ }
+
+ /* PTR should now point to the start of a string. */
+ if (c != '@')
+ error (1, 0, "expected @-string at `%c' in %s", c, rcsbuf->filename);
+
+ /* Optimize the common case of a value composed of a single
+ '@' string. */
+
+ rcsbuf->at_string = 1;
+
+ ++ptr;
+
+ *strp = ptr;
+
+ while (1)
+ {
+ while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
+ {
+ /* Note that we pass PTREND as the PTR value to
+ rcsbuf_fill, so that we will wind up setting PTR to
+ the location corresponding to the old PTREND, so
+ that we don't search the same bytes again. */
+ ptr = rcsbuf_fill (rcsbuf, ptrend, NULL, strp);
+ if (ptr == NULL)
+ error (1, 0,
+ "EOF while looking for end of string in RCS file %s",
+ rcsbuf->filename);
+ ptrend = rcsbuf->ptrend;
+ }
+
+ /* Handle the special case of an '@' right at the end of
+ the known bytes. */
+ if (pat + 1 >= ptrend)
+ {
+ /* Note that we pass PAT, not PTR, here. */
+ pat = rcsbuf_fill (rcsbuf, pat, NULL, strp);
+ if (pat == NULL)
+ {
+ /* EOF here is OK; it just means that the last
+ character of the file was an '@' terminating a
+ value for a key type which does not require a
+ trailing ';'. */
+ pat = rcsbuf->ptrend - 1;
+
+ }
+ ptrend = rcsbuf->ptrend;
+
+ /* Note that the value of PTR is bogus here. This is
+ OK, because we don't use it. */
+ }
+
+ if (pat + 1 >= ptrend || pat[1] != '@')
+ break;
+
+ /* We found an '@' pair in the string. Keep looking. */
+ ++rcsbuf->embedded_at;
+ ptr = pat + 2;
+ }
+
+ /* Here PAT points to the final '@' in the string. */
+
+ *pat = '\0';
+
+ vlen = pat - *strp;
+ if (vlen == 0)
+ *strp = NULL;
+ rcsbuf->vlen = vlen;
+ rcsbuf->ptr = pat + 1;
+
+ return 1;
+
+#undef my_whitespace
+}
+
+/* Read an RCS `word', in the sense of rcsfile(5) (an id, a num, a
+ @-delimited string, or `:'). Store the result in WORDP. If a
+ `;' is reached without reading any text, the result is NULL. */
+
+static int
+rcsbuf_getword (rcsbuf, wordp)
+ struct rcsbuffer *rcsbuf;
+ char **wordp;
+{
+ register const char * const my_spacetab = spacetab;
+ register char *ptr, *ptrend;
+ char c;
+
+#define my_whitespace(c) (my_spacetab[(unsigned char)c] != 0)
+
+ rcsbuf->vlen = 0;
+ rcsbuf->at_string = 0;
+ rcsbuf->embedded_at = 0;
+
+ ptr = rcsbuf->ptr;
+ ptrend = rcsbuf->ptrend;
+
+ /* Sanity check. */
+ if (ptr < rcsbuf_buffer || ptr > rcsbuf_buffer + rcsbuf_buffer_size)
+ abort ();
+
+ /* If the pointer is more than RCSBUF_BUFSIZE bytes into the
+ buffer, move back to the start of the buffer. This keeps the
+ buffer from growing indefinitely. */
+ if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
+ {
+ int len;
+
+ len = ptrend - ptr;
+
+ /* Sanity check: we don't read more than RCSBUF_BUFSIZE bytes
+ at a time, so we can't have more bytes than that past PTR. */
+ if (len > RCSBUF_BUFSIZE)
+ abort ();
+
+ /* Update the POS field, which holds the file offset of the
+ first byte in the RCSBUF_BUFFER buffer. */
+ rcsbuf->pos += ptr - rcsbuf_buffer;
+
+ memcpy (rcsbuf_buffer, ptr, len);
+ ptr = rcsbuf_buffer;
+ ptrend = ptr + len;
+ rcsbuf->ptrend = ptrend;
+ }
+
+ /* Skip leading whitespace. */
+
+ while (1)
+ {
+ if (ptr >= ptrend)
+ {
+ ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
+ if (ptr == NULL)
+ error (1, 0, "unexpected end of file reading %s",
+ rcsbuf->filename);
+ ptrend = rcsbuf->ptrend;
+ }
+
+ c = *ptr;
+ if (! my_whitespace (c))
+ break;
+
+ ++ptr;
+ }
+
+ /* If we have reached `;', there is no value. */
+ if (c == ';')
+ {
+ *wordp = NULL;
+ *ptr++ = '\0';
+ rcsbuf->ptr = ptr;
+ rcsbuf->vlen = 0;
+ return 1;
+ }
+
+ /* PTR now points to the start of a value. Find out whether it is
+ a num, an id, a string or a colon. */
+ if (c == ':')
+ {
+ *wordp = ptr++;
+ rcsbuf->ptr = ptr;
+ rcsbuf->vlen = 1;
+ return 1;
+ }
+
+ if (c == '@')
+ {
+ char *pat;
+ size_t vlen;
+
+ /* Optimize the common case of a value composed of a single
+ '@' string. */
+
+ rcsbuf->at_string = 1;
+
+ ++ptr;
+
+ *wordp = ptr;
+
+ while (1)
+ {
+ while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
+ {
+ /* Note that we pass PTREND as the PTR value to
+ rcsbuf_fill, so that we will wind up setting PTR to
+ the location corresponding to the old PTREND, so
+ that we don't search the same bytes again. */
+ ptr = rcsbuf_fill (rcsbuf, ptrend, NULL, wordp);
+ if (ptr == NULL)
+ error (1, 0,
+ "EOF while looking for end of string in RCS file %s",
+ rcsbuf->filename);
+ ptrend = rcsbuf->ptrend;
+ }
+
+ /* Handle the special case of an '@' right at the end of
+ the known bytes. */
+ if (pat + 1 >= ptrend)
+ {
+ /* Note that we pass PAT, not PTR, here. */
+ pat = rcsbuf_fill (rcsbuf, pat, NULL, wordp);
+ if (pat == NULL)
+ {
+ /* EOF here is OK; it just means that the last
+ character of the file was an '@' terminating a
+ value for a key type which does not require a
+ trailing ';'. */
+ pat = rcsbuf->ptrend - 1;
+
+ }
+ ptrend = rcsbuf->ptrend;
+
+ /* Note that the value of PTR is bogus here. This is
+ OK, because we don't use it. */
+ }
+
+ if (pat + 1 >= ptrend || pat[1] != '@')
+ break;
+
+ /* We found an '@' pair in the string. Keep looking. */
+ ++rcsbuf->embedded_at;
+ ptr = pat + 2;
+ }
+
+ /* Here PAT points to the final '@' in the string. */
+
+ *pat = '\0';
+
+ vlen = pat - *wordp;
+ if (vlen == 0)
+ *wordp = NULL;
+ rcsbuf->vlen = vlen;
+ rcsbuf->ptr = pat + 1;
+
+ return 1;
+ }
+
+ /* C is neither `:', `;' nor `@', so it should be the start of a num
+ or an id. Make sure it is not another special character. */
+ if (c == '$' || c == '.' || c == ',')
+ {
+ error (1, 0, "illegal special character in RCS field in %s",
+ rcsbuf->filename);
+ }
+
+ *wordp = ptr;
+ while (1)
+ {
+ if (ptr >= ptrend)
+ {
+ ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, wordp);
+ if (ptr == NULL)
+ error (1, 0, "unexpected end of file reading %s",
+ rcsbuf->filename);
+ ptrend = rcsbuf->ptrend;
+ }
+
+ /* Legitimate ID characters are digits, dots and any `graphic
+ printing character that is not a special.' This test ought
+ to do the trick. */
+ c = *ptr;
+ if (isprint (c) &&
+ c != ';' && c != '$' && c != ',' && c != '@' && c != ':')
+ {
+ ++ptr;
+ continue;
+ }
+ break;
+ }
+
+ /* PTR points to the last non-id character in this word, and C is
+ the character in its memory cell. Check to make sure that it
+ is a legitimate word delimiter -- whitespace or semicolon. */
+ if (c == ';' || my_whitespace (c))
+ {
+ rcsbuf->vlen = ptr - *wordp;
+ rcsbuf->ptr = ptr;
+ return 1;
+ }
+
+ error (1, 0, "illegal special character in RCS field in %s",
+ rcsbuf->filename);
+ /* Shut up compiler warnings. */
+ return 0;
+
+#undef my_whitespace
+}
+
/* Read an RCS revision number from an RCS file. This sets *REVP to
point to the revision number; it will point to space that is
managed by the rcsbuf functions, and is only good until the next
@@ -1875,6 +2357,89 @@ RCS_getversion (rcs, tag, date, force_tag_match, simple_tag)
}
/*
+ * Get existing revision number corresponding to tag or revision.
+ * Similar to RCS_gettag but less interpretation imposed.
+ * For example:
+ * -- If tag designates a magic branch, RCS_tag2rev
+ * returns the magic branch number.
+ * -- If tag is a branch tag, returns the branch number, not
+ * the revision of the head of the branch.
+ * If tag or revision is not valid or does not exist in file,
+ * exit with error.
+ */
+char *
+RCS_tag2rev (rcs, tag)
+ RCSNode *rcs;
+ char *tag;
+{
+ char *rev, *pa, *pb;
+ int i;
+
+ assert (rcs != NULL);
+
+ if (rcs->flags & PARTIAL)
+ RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
+
+ /* If a valid revision, try to look it up */
+ if ( RCS_valid_rev (tag) )
+ {
+ /* Make a copy so we can scribble on it */
+ rev = xstrdup (tag);
+
+ /* If revision exists, return the copy */
+ if (RCS_exist_rev (rcs, tag))
+ return rev;
+
+ /* Nope, none such. If tag is not a branch we're done. */
+ i = numdots (rev);
+ if ((i & 1) == 1 )
+ {
+ pa = strrchr (rev, '.');
+ if (i == 1 || *(pa-1) != RCS_MAGIC_BRANCH || *(pa-2) != '.')
+ {
+ free (rev);
+ error (1, 0, "revision `%s' does not exist", tag);
+ }
+ }
+
+ /* Tag is branch, but does not exist, try corresponding
+ * magic branch tag.
+ *
+ * FIXME: assumes all magic branches are of
+ * form "n.n.n ... .0.n". I'll fix if somebody can
+ * send me a method to get a magic branch tag with
+ * the 0 in some other position -- <dan@gasboy.com>
+ */
+ pa = strrchr (rev, '.');
+ pb = xmalloc (strlen (rev) + 3);
+ *pa++ = 0;
+ (void) sprintf (pb, "%s.%d.%s", rev, RCS_MAGIC_BRANCH, pa);
+ free (rev);
+ rev = pb;
+ if (RCS_exist_rev (rcs, rev))
+ return rev;
+ error (1, 0, "revision `%s' does not exist", tag);
+ }
+
+
+ RCS_check_tag (tag); /* exit if not a valid tag */
+
+ /* If tag is "HEAD", special case to get head RCS revision */
+ if (tag && (strcmp (tag, TAG_HEAD) == 0))
+ return (RCS_head (rcs));
+
+ /* If valid tag let translate_symtag say yea or nay. */
+ rev = translate_symtag (rcs, tag);
+
+ if (rev)
+ return rev;
+
+ error (1, 0, "tag `%s' does not exist", tag);
+ /* NOT REACHED -- error (1 ... ) does not return here */
+ return 0;
+}
+
+/*
* Find the revision for a specific tag.
* If force_tag_match is set, return NULL if an exact match is not
* possible otherwise return RCS_head (). We are careful to look for
@@ -2344,6 +2909,41 @@ RCS_getbranch (rcs, tag, force_tag_match)
return (xstrdup (vn->version));
}
+/* Returns the head of the branch which REV is on. REV can be a
+ branch tag or non-branch tag; symbolic or numeric.
+
+ Returns a newly malloc'd string. Returns NULL if a symbolic name
+ isn't found. */
+
+char *
+RCS_branch_head (rcs, rev)
+ RCSNode *rcs;
+ char *rev;
+{
+ char *num;
+ char *br;
+ char *retval;
+
+ assert (rcs != NULL);
+
+ if (RCS_nodeisbranch (rcs, rev))
+ return RCS_getbranch (rcs, rev, 1);
+
+ if (isdigit (*rev))
+ num = xstrdup (rev);
+ else
+ {
+ num = translate_symtag (rcs, rev);
+ if (num == NULL)
+ return NULL;
+ }
+ br = truncate_revnum (num);
+ retval = RCS_getbranch (rcs, br, 1);
+ free (br);
+ free (num);
+ return retval;
+}
+
/* Get the branch point for a particular branch, that is the first
revision on that branch. For example, RCS_getbranchpoint (rcs,
"1.3.2") will normally return "1.3.2.1". TARGET may be either a
@@ -2871,6 +3471,40 @@ RCS_check_tag (tag)
}
/*
+ * TRUE if argument has valid syntax for an RCS revision or
+ * branch number. All characters must be digits or dots, first
+ * and last characters must be digits, and no two consecutive
+ * characters may be dots.
+ *
+ * Intended for classifying things, so this function doesn't
+ * call error.
+ */
+int
+RCS_valid_rev (rev)
+ char *rev;
+{
+ char last, c;
+ last = *rev++;
+ if (!isdigit (last))
+ return 0;
+ while ((c = *rev++)) /* Extra parens placate -Wall gcc option */
+ {
+ if (c == '.')
+ {
+ if (last == '.')
+ return 0;
+ continue;
+ }
+ last = c;
+ if (!isdigit (c))
+ return 0;
+ }
+ if (!isdigit (last))
+ return 0;
+ return 1;
+}
+
+/*
* Return true if RCS revision with TAG is a dead revision.
*/
int
@@ -3533,11 +4167,10 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
size_t loglen;
Node *vp = NULL;
#ifdef PRESERVE_PERMISSIONS_SUPPORT
- uid_t rcs_owner;
- gid_t rcs_group;
+ uid_t rcs_owner = (uid_t) -1;
+ gid_t rcs_group = (gid_t) -1;
mode_t rcs_mode;
- int change_rcs_owner = 0;
- int change_rcs_group = 0;
+ int change_rcs_owner_or_group = 0;
int change_rcs_mode = 0;
int special_file = 0;
unsigned long devnum_long;
@@ -3689,7 +4322,6 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
{
RCSVers *vers;
Node *info;
- struct hardlink_info *hlinfo;
vp = findnode (rcs->versions, rev == NULL ? rcs->head : rev);
if (vp == NULL)
@@ -3716,7 +4348,7 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
whether it should be considered an error for `dest' to exist
at this point. If so, the unlink call should be removed and
`symlink' should signal the error. -twp) */
- if (unlink (dest) < 0 && existence_error (errno))
+ if (unlink (dest) < 0 && !existence_error (errno))
error (1, errno, "cannot remove %s", dest);
if (symlink (info->data, dest) < 0)
error (1, errno, "cannot create symbolic link from %s to %s",
@@ -3738,64 +4370,36 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (workfile != NULL)
{
- info = findnode (vers->other_delta, "hardlinks");
- if (info != NULL)
+ List *links = vers->hardlinks;
+ if (links != NULL)
{
- char *links = xstrdup (info->data);
- char *working_dir = xgetwd();
- char *p, *file = NULL;
- Node *n, *uptodate_link;
+ Node *uptodate_link;
/* For each file in the hardlinks field, check to see
if it exists, and if so, if it has been checked out
- this iteration. */
- uptodate_link = NULL;
- for (p = strtok (links, " ");
- p != NULL && uptodate_link == NULL;
- p = strtok (NULL, " "))
- {
- file = (char *)
- xmalloc (sizeof(char) *
- (strlen(working_dir) + strlen(p) + 2));
- sprintf (file, "%s/%s", working_dir, p);
- n = lookup_file_by_inode (file);
- if (n == NULL)
- {
- if (strcmp (p, workfile) != 0)
- {
- /* One of the files that WORKFILE should be
- linked to is not even in the working directory.
- The user should probably be warned. */
- error (0, 0,
- "warning: %s should be hardlinked to %s, but is missing",
- p, workfile);
- }
- free (file);
- continue;
- }
+ this iteration. When walklist returns, uptodate_link
+ should point to a hardlist node representing a file
+ in `links' which has recently been checked out, or
+ NULL if no file in `links' has yet been checked out. */
- /* hlinfo may be NULL if, for instance, a file is being
- removed. */
- hlinfo = (struct hardlink_info *) n->data;
- if (hlinfo && hlinfo->checked_out)
- uptodate_link = n;
- free (file);
- }
- free (links);
- free (working_dir);
+ uptodate_link = NULL;
+ (void) walklist (links, find_checkedout_proc, &uptodate_link);
+ dellist (&links);
/* If we've found a file that `workfile' is supposed to be
linked to, and it has been checked out since CVS was
- invoked, then simply link workfile to that file.
+ invoked, then simply link workfile to that file and return.
- If one of these conditions is not met, then we're
- checking out workfile to a temp file or stdout, or
- workfile is the first one in its hardlink group to be
- checked out. Either way we must continue with a full
+ If one of these conditions is not met, then
+ workfile is the first one in its hardlink group to
+ be checked out, and we must continue with a full
checkout. */
if (uptodate_link != NULL)
{
+ struct hardlink_info *hlinfo =
+ (struct hardlink_info *) uptodate_link->data;
+
if (link (uptodate_link->key, workfile) < 0)
error (1, errno, "cannot link %s to %s",
workfile, uptodate_link->key);
@@ -3812,13 +4416,13 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
info = findnode (vers->other_delta, "owner");
if (info != NULL)
{
- change_rcs_owner = 1;
+ change_rcs_owner_or_group = 1;
rcs_owner = (uid_t) strtoul (info->data, NULL, 10);
}
info = findnode (vers->other_delta, "group");
if (info != NULL)
{
- change_rcs_group = 1;
+ change_rcs_owner_or_group = 1;
rcs_group = (gid_t) strtoul (info->data, NULL, 10);
}
info = findnode (vers->other_delta, "permissions");
@@ -3997,10 +4601,10 @@ RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat)
if (!special_file && fclose (ofp) < 0)
error (1, errno, "cannot close %s", workfile);
- if (change_rcs_owner || change_rcs_group)
+ if (change_rcs_owner_or_group)
{
if (chown (workfile, rcs_owner, rcs_group) < 0)
- error (0, errno, "could not change file ownership on %s",
+ error (0, errno, "could not change owner or group of %s",
workfile);
}
@@ -4435,7 +5039,6 @@ RCS_checkin (rcs, workfile, message, rev, flags)
Node *np;
struct stat sb;
char buf[64]; /* static buffer should be safe: see usage. -twp */
- char *fullpath;
delta->other_delta = getlist();
@@ -4490,25 +5093,7 @@ RCS_checkin (rcs, workfile, message, rev, flags)
}
/* Save hardlinks. */
- fullpath = xgetwd();
- fullpath = xrealloc (fullpath,
- strlen(fullpath) + strlen(workfile) + 2);
- sprintf (fullpath + strlen(fullpath), "/%s", workfile);
-
- np = lookup_file_by_inode (fullpath);
- if (np == NULL)
- {
- error (1, 0, "lost information on %s's linkage", workfile);
- }
- else
- {
- struct hardlink_info *hlinfo;
- hlinfo = (struct hardlink_info *) np->data;
- np = getnode();
- np->key = xstrdup ("hardlinks");
- np->data = xstrdup (hlinfo->links);
- (void) addnode (delta->other_delta, np);
- }
+ delta->hardlinks = list_linked_files_on_disk (workfile);
}
}
#endif
@@ -5000,6 +5585,9 @@ RCS_cmp_file (rcs, rev, options, filename)
#endif
{
fp = CVS_FOPEN (filename, binary ? FOPEN_BINARY_READ : "r");
+ if (fp == NULL)
+ /* FIXME-update-dir: should include update_dir in message. */
+ error (1, errno, "cannot open file %s for comparing", filename);
data.filename = filename;
data.fp = fp;
@@ -5191,8 +5779,11 @@ RCS_setbranch (rcs, rev)
}
/* Lock revision REV. LOCK_QUIET is 1 to suppress output. FIXME:
- This is only required because the RCS ci program requires a lock.
- If we eventually do the checkin ourselves, this can become a no-op. */
+ Most of the callers only call us because RCS_checkin still tends to
+ like a lock (a relic of old behavior inherited from the RCS ci
+ program). If we clean this up, only "cvs admin -l" will still need
+ to call RCS_lock. */
+
/* FIXME-twp: if a lock owned by someone else is broken, should this
send mail to the lock owner? Prompt user? It seems like such an
obscure situation for CVS as almost not worth worrying much
@@ -5261,6 +5852,18 @@ RCS_lock (rcs, rev, lock_quiet)
return 0;
}
+#if 0
+ /* Well, first of all, "rev" below should be "xrev" to avoid
+ core dumps. But more importantly, should we really be
+ breaking the lock unconditionally? What CVS 1.9 does (via
+ RCS) is to prompt "Revision 1.1 is already locked by fred.
+ Do you want to break the lock? [ny](n): ". Well, we don't
+ want to interact with the user (certainly not at the
+ server/protocol level, and probably not in the command-line
+ client), but isn't it more sensible to give an error and
+ let the user run "cvs admin -u" if they want to break the
+ lock? */
+
/* Break the lock. */
if (!lock_quiet)
{
@@ -5268,6 +5871,9 @@ RCS_lock (rcs, rev, lock_quiet)
cvs_output (" unlocked\n", 0);
}
delnode (p);
+#else
+ error (1, 0, "Revision %s is already locked by %s", xrev, p->data);
+#endif
}
/* Create a new lock. */
@@ -5983,6 +6589,52 @@ RCS_delete_revs (rcs, tag1, tag2, inclusive)
return status;
}
+
+/*
+ * TRUE if there exists a symbolic tag "tag" in file.
+ */
+int
+RCS_exist_tag (rcs, tag)
+ RCSNode *rcs;
+ char *tag;
+{
+
+ assert (rcs != NULL);
+
+ if (findnode (RCS_symbols (rcs), tag))
+ return 1;
+ return 0;
+
+}
+
+/*
+ * TRUE if RCS revision number "rev" exists.
+ * This includes magic branch revisions, not found in rcs->versions,
+ * but only in rcs->symbols, requiring a list walk to find them.
+ * Take advantage of list walk callback function already used by
+ * RCS_delete_revs, above.
+ */
+int
+RCS_exist_rev (rcs, rev)
+ RCSNode *rcs;
+ char *rev;
+{
+
+ assert (rcs != NULL);
+
+ if (rcs->flags & PARTIAL)
+ RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
+
+ if (findnode(rcs->versions, rev) != 0)
+ return 1;
+
+ if (walklist (RCS_symbols(rcs), findtag, rev) != 0)
+ return 1;
+
+ return 0;
+
+}
+
/* RCS_deltas and friends. Processing of the deltas in RCS files. */
@@ -6779,7 +7431,7 @@ getdelta (rcsbuf, rcsfile, keyp, valp)
char **valp;
{
RCSVers *vnode;
- char *key, *value, *cp;
+ char *key, *value, *keybuf, *valbuf, *cp;
Node *kv;
/* Get revision number if it wasn't passed in. This uses
@@ -6843,7 +7495,8 @@ unable to parse %s; `author' not in the expected place", rcsfile);
error (1, 0, "\
unable to parse %s; `state' not in the expected place", rcsfile);
vnode->state = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *) NULL);
- if (STREQ (value, "dead"))
+ /* The value is optional, according to rcsfile(5). */
+ if (value != NULL && STREQ (value, "dead"))
{
vnode->dead = 1;
}
@@ -6894,11 +7547,80 @@ unable to parse %s; `state' not in the expected place", rcsfile);
*/
while (1)
{
- if (! rcsbuf_getkey (rcsbuf, &key, &value))
+ int len;
+ size_t valbuflen;
+
+ key = NULL;
+
+ if (! rcsbuf_getid (rcsbuf, &keybuf))
error (1, 0, "unexpected end of file reading %s", rcsfile);
+ /* rcsbuf_getid did not terminate the key, so copy it to new space. */
+ len = rcsbuf->ptr - keybuf;
+ key = (char *) xmalloc (sizeof(char) * (len + 1));
+ strncpy (key, keybuf, len);
+ key[len] = '\0';
+
+ /* The `desc' keyword has only a single string value, with no
+ trailing semicolon, so it must be handled specially. */
if (STREQ (key, RCSDESC))
+ {
+ (void) rcsbuf_getstring (rcsbuf, &valbuf);
+ value = rcsbuf_valcopy (rcsbuf, valbuf, 1, &valbuflen);
break;
+ }
+
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
+ /* The `hardlinks' value is a group of words, which must
+ be parsed separately and added as a list to vnode->hardlinks. */
+ if (STREQ (key, "hardlinks"))
+ {
+ Node *n;
+
+ vnode->hardlinks = getlist();
+ while (1)
+ {
+ if (! rcsbuf_getword (rcsbuf, &valbuf))
+ error (1, 0, "unexpected end of file reading %s", rcsfile);
+ if (valbuf == NULL)
+ break;
+ n = getnode();
+ n->key = rcsbuf_valcopy (rcsbuf, valbuf, 1, NULL);
+ addnode (vnode->hardlinks, n);
+ }
+ continue;
+ }
+#endif
+
+ /* Get the value. */
+ value = NULL;
+ while (1)
+ {
+ if (! rcsbuf_getword (rcsbuf, &valbuf))
+ error (1, 0, "unexpected end of file reading %s", rcsfile);
+ if (valbuf == NULL)
+ break;
+
+ /* Copy valbuf to new space so we can polish it, then
+ append it to value. */
+
+ if (value == NULL)
+ {
+ value = rcsbuf_valcopy (rcsbuf, valbuf, 1, &valbuflen);
+ }
+ else
+ {
+ char *temp_value;
+
+ temp_value = rcsbuf_valcopy (rcsbuf, valbuf, 1, &valbuflen);
+ len = strlen (value);
+ value = (char *) xrealloc
+ (value, sizeof(char) * (len + valbuflen + 2));
+ value[len] = ' ';
+ strcpy (value + len + 1, temp_value);
+ free (temp_value);
+ }
+ }
/* Enable use of repositories created by certain obsolete
versions of CVS. This code should remain indefinately;
@@ -6927,8 +7649,8 @@ unable to parse %s; `state' not in the expected place", rcsfile);
vnode->other_delta = getlist ();
kv = getnode ();
kv->type = RCSFIELD;
- kv->key = xstrdup (key);
- kv->data = rcsbuf_valcopy (rcsbuf, value, 1, (size_t *) NULL);
+ kv->key = key;
+ kv->data = value;
if (addnode (vnode->other_delta, kv) != 0)
{
/* Complaining about duplicate keys in newphrases seems
@@ -7118,6 +7840,36 @@ putrcsfield_proc (node, vfp)
return 0;
}
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
+
+/* Save a filename in a `hardlinks' RCS field. NODE->KEY will contain
+ a full pathname, but currently only basenames are stored in the RCS
+ node. Assume that the filename includes nasty characters and
+ @-escape it. */
+
+static int
+puthardlink_proc (node, vfp)
+ Node *node;
+ void *vfp;
+{
+ FILE *fp = (FILE *) vfp;
+ char *basename = strrchr (node->key, '/');
+
+ if (basename == NULL)
+ basename = node->key;
+ else
+ ++basename;
+
+ putc ('\t', fp);
+ putc ('@', fp);
+ (void) expand_at_signs (basename, strlen (basename), fp);
+ putc ('@', fp);
+
+ return 0;
+}
+
+#endif
+
/* Output the admin node for RCS into stream FP. */
static void
@@ -7203,6 +7955,14 @@ putdelta (vers, fp)
walklist (vers->other_delta, putrcsfield_proc, fp);
+#ifdef PRESERVE_PERMISSIONS_SUPPORT
+ if (vers->hardlinks)
+ {
+ fprintf (fp, "\nhardlinks");
+ walklist (vers->hardlinks, puthardlink_proc, fp);
+ putc (';', fp);
+ }
+#endif
putc ('\n', fp);
}
@@ -7532,8 +8292,6 @@ rcs_internal_lockfile (rcsfile)
error (1, errno, "could not open lock file `%s'", lockfile);
}
- free (lockfile);
-
/* Force the file permissions, and return a stream object. */
/* Because we change the modes later, we don't worry about
this in the non-HAVE_FCHMOD case. */
@@ -7544,6 +8302,9 @@ rcs_internal_lockfile (rcsfile)
fp = fdopen (fd, FOPEN_BINARY_WRITE);
if (fp == NULL)
error (1, errno, "cannot fdopen %s", lockfile);
+
+ free (lockfile);
+
return fp;
}
diff --git a/gnu/usr.bin/cvs/src/server.c b/gnu/usr.bin/cvs/src/server.c
index 06e293e0c43..0bcc9a225fa 100644
--- a/gnu/usr.bin/cvs/src/server.c
+++ b/gnu/usr.bin/cvs/src/server.c
@@ -366,7 +366,8 @@ mkdir_p (dir)
int saved_errno = errno;
if (saved_errno != EEXIST
- && (saved_errno != EACCES || !isdir (q)))
+ && ((saved_errno != EACCES && saved_errno != EROFS)
+ || !isdir (q)))
{
retval = saved_errno;
goto done;
@@ -635,6 +636,18 @@ server_pathname_check (path)
and is unlikely to do us any good here. It also is probably capable
of being a security hole in the anonymous readonly case. */
if (isabsolute (path))
+ /* Giving an error is actually kind of a cop-out, in the sense
+ that it would be nice for "cvs co -d /foo/bar/baz" to work.
+ A quick fix in the server would be requiring Max-dotdot of
+ at least one if pathnames are absolute, and then putting
+ /abs/foo/bar/baz in the temp dir beside the /d/d/d stuff.
+ A cleaner fix in the server might be to decouple the
+ pathnames we pass back to the client from pathnames in our
+ temp directory (this would also probably remove the need
+ for Max-dotdot). A fix in the client would have the client
+ turn it into "cd /foo/bar; cvs co -d baz" (more or less).
+ This probably has some problems with pathnames which appear
+ in messages. */
error (1, 0, "absolute pathname `%s' illegal for server", path);
if (pathname_levels (path) > max_dotdot_limit)
{
@@ -2256,6 +2269,9 @@ error \n");
/* We shouldn't have any partial lines from cvs_output and
cvs_outerr, but we handle them here in case there is a bug. */
+ /* FIXME: appending a newline, rather than using "MT" as we
+ do in the child process, is probably not really a very good
+ way to "handle" them. */
if (! buf_empty_p (saved_output))
{
buf_append_char (saved_output, '\n');
@@ -2326,6 +2342,19 @@ error \n");
exitstatus = (*command) (argument_count, argument_vector);
+ /* Output any partial lines. If the client doesn't support
+ "MT", we just throw out the partial line, like old versions
+ of CVS did, since the protocol can't support this. */
+ if (supported_response ("MT") && ! buf_empty_p (saved_output))
+ {
+ buf_output0 (protocol, "MT text ");
+ buf_append_buffer (protocol, saved_output);
+ buf_output (protocol, "\n", 1);
+ buf_send_counted (protocol);
+ }
+ /* For now we just discard partial lines on stderr. I suspect
+ that CVS can't write such lines unless there is a bug. */
+
/*
* When we exit, that will close the pipes, giving an EOF to
* the parent.
@@ -2840,8 +2869,9 @@ server_register (name, version, timestamp, options, tag, date, conflict)
(void) fprintf (stderr,
"%c-> server_register(%s, %s, %s, %s, %s, %s, %s)\n",
(server_active) ? 'S' : ' ', /* silly */
- name, version, timestamp, options, tag ? tag : "",
- date ? date : "", conflict ? conflict : "");
+ name, version, timestamp ? timestamp : "", options,
+ tag ? tag : "", date ? date : "",
+ conflict ? conflict : "");
}
if (entries_line != NULL)
@@ -3078,7 +3108,7 @@ static void
serve_status (arg)
char *arg;
{
- do_cvs_command ("status", status);
+ do_cvs_command ("status", cvsstatus);
}
static void
@@ -3580,7 +3610,7 @@ CVS server internal error: unhandled case in server_updated");
if ((updated == SERVER_UPDATED
|| updated == SERVER_PATCHED
|| updated == SERVER_RCS_DIFF)
- && filebuf != NULL
+ && filebuf == NULL
/* But if we are joining, we'll need the file when we call
join_file. */
&& !joining ())
@@ -4782,25 +4812,23 @@ check_password (username, password, repository)
/* No cvs password found, so try /etc/passwd. */
const char *found_passwd = NULL;
+ struct passwd *pw;
#ifdef HAVE_GETSPNAM
- struct spwd *pw;
+ struct spwd *spw;
- pw = getspnam (username);
- if (pw != NULL)
+ spw = getspnam (username);
+ if (spw != NULL)
{
- found_passwd = pw->sp_pwdp;
+ found_passwd = spw->sp_pwdp;
}
-#else
- struct passwd *pw;
+#endif
- pw = getpwnam (username);
- if (pw != NULL)
+ if (found_passwd == NULL && (pw = getpwnam (username)) != NULL)
{
found_passwd = pw->pw_passwd;
}
-#endif
- if (pw == NULL)
+ if (found_passwd == NULL)
{
printf ("E Fatal error, aborting.\n\
error 0 %s: no such user\n", username);
@@ -4818,8 +4846,9 @@ error 0 %s: no such user\n", username);
exit (EXIT_FAILURE);
}
- if (found_passwd && *found_passwd)
+ if (*found_passwd)
{
+ /* user exists and has a password */
host_user = ((! strcmp (found_passwd,
crypt (password, found_passwd)))
? username : NULL);
@@ -4827,11 +4856,14 @@ error 0 %s: no such user\n", username);
}
else if (password && *password)
{
+ /* user exists and has no system password, but we got
+ one as parameter */
host_user = username;
goto handle_return;
}
else
{
+ /* user exists but has no password at all */
host_user = NULL;
goto handle_return;
}
@@ -5590,7 +5622,7 @@ cvs_output_binary (str, len)
if (error_use_protocol)
buf = buf_to_net;
- else if (server_active)
+ else
buf = protocol;
if (!supported_response ("Mbinary"))
diff --git a/gnu/usr.bin/cvs/src/update.c b/gnu/usr.bin/cvs/src/update.c
index 7933dd23c86..fbd4995b009 100644
--- a/gnu/usr.bin/cvs/src/update.c
+++ b/gnu/usr.bin/cvs/src/update.c
@@ -530,7 +530,6 @@ get_linkinfo_proc (callerdat, finfo)
hlinfo->status = (Ctype) 0; /* is this dumb? */
hlinfo->checked_out = 0;
- hlinfo->links = NULL;
linkp->data = (char *) hlinfo;
@@ -2505,8 +2504,8 @@ special_file_mismatch (finfo, rev1, rev2)
dev_t rev1_dev, rev2_dev;
char *rev1_symlink = NULL;
char *rev2_symlink = NULL;
- char *rev1_hardlinks = NULL;
- char *rev2_hardlinks = NULL;
+ List *rev1_hardlinks;
+ List *rev2_hardlinks;
int check_uids, check_gids, check_modes;
int result;
@@ -2544,7 +2543,7 @@ special_file_mismatch (finfo, rev1, rev2)
if (S_ISBLK (rev1_mode) || S_ISCHR (rev1_mode))
rev1_dev = sb.st_rdev;
}
- rev1_hardlinks = list_files_linked_to (finfo->file);
+ rev1_hardlinks = list_linked_files_on_disk (finfo->file);
}
else
{
@@ -2595,11 +2594,9 @@ special_file_mismatch (finfo, rev1, rev2)
finfo->file, rev1, ftype);
}
- n = findnode (vp->other_delta, "hardlinks");
- if (n == NULL)
- rev1_hardlinks = xstrdup ("");
- else
- rev1_hardlinks = xstrdup (n->data);
+ rev1_hardlinks = vp->hardlinks;
+ if (rev1_hardlinks == NULL)
+ rev1_hardlinks = getlist();
}
}
@@ -2619,7 +2616,7 @@ special_file_mismatch (finfo, rev1, rev2)
if (S_ISBLK (rev2_mode) || S_ISCHR (rev2_mode))
rev2_dev = sb.st_rdev;
}
- rev2_hardlinks = list_files_linked_to (finfo->file);
+ rev2_hardlinks = list_linked_files_on_disk (finfo->file);
}
else
{
@@ -2670,11 +2667,9 @@ special_file_mismatch (finfo, rev1, rev2)
finfo->file, rev2, ftype);
}
- n = findnode (vp->other_delta, "hardlinks");
- if (n == NULL)
- rev2_hardlinks = xstrdup ("");
- else
- rev2_hardlinks = xstrdup (n->data);
+ rev2_hardlinks = vp->hardlinks;
+ if (rev2_hardlinks == NULL)
+ rev2_hardlinks = getlist();
}
}
@@ -2755,7 +2750,7 @@ special_file_mismatch (finfo, rev1, rev2)
}
/* Compare hard links. */
- if (strcmp (rev1_hardlinks, rev2_hardlinks) != 0)
+ if (compare_linkage_lists (rev1_hardlinks, rev2_hardlinks) == 0)
{
error (0, 0, "%s: hard linkage of %s and %s do not match",
finfo->file,
@@ -2770,9 +2765,9 @@ special_file_mismatch (finfo, rev1, rev2)
if (rev2_symlink != NULL)
free (rev2_symlink);
if (rev1_hardlinks != NULL)
- free (rev1_hardlinks);
+ dellist (&rev1_hardlinks);
if (rev2_hardlinks != NULL)
- free (rev2_hardlinks);
+ dellist (&rev2_hardlinks);
return result;
#else