summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortholo <tholo@openbsd.org>1996-10-18 04:18:46 +0000
committertholo <tholo@openbsd.org>1996-10-18 04:18:46 +0000
commit7e4d5a85f91e22adbbb2241021e71287d24b0996 (patch)
treec0434cf3e92c0f93e6c3f461c97996cd81d53b06
parentMissing files from import (diff)
downloadwireguard-openbsd-7e4d5a85f91e22adbbb2241021e71287d24b0996.tar.xz
wireguard-openbsd-7e4d5a85f91e22adbbb2241021e71287d24b0996.zip
Integrate local changes
-rw-r--r--gnu/usr.bin/cvs/Makefile.in57
-rw-r--r--gnu/usr.bin/cvs/configure480
-rw-r--r--gnu/usr.bin/cvs/configure.in49
-rw-r--r--gnu/usr.bin/cvs/contrib/Makefile.in6
-rw-r--r--gnu/usr.bin/cvs/lib/getdate.c1848
-rw-r--r--gnu/usr.bin/cvs/lib/getdate.y19
-rw-r--r--gnu/usr.bin/cvs/lib/memmove.c57
-rw-r--r--gnu/usr.bin/cvs/macintosh/maccvs.projects.sit.hqx270
-rw-r--r--gnu/usr.bin/cvs/macintosh/maccvs.rsrc.sit.hqx14
-rw-r--r--gnu/usr.bin/cvs/macintosh/maccvs165.patch2509
-rw-r--r--gnu/usr.bin/cvs/src/README-rm-add31
-rw-r--r--gnu/usr.bin/cvs/src/checkout.c133
-rw-r--r--gnu/usr.bin/cvs/src/commit.c736
-rw-r--r--gnu/usr.bin/cvs/src/cvs.h342
-rw-r--r--gnu/usr.bin/cvs/src/ignore.c84
-rw-r--r--gnu/usr.bin/cvs/src/lock.c151
-rw-r--r--gnu/usr.bin/cvs/src/main.c885
-rw-r--r--gnu/usr.bin/cvs/src/patch.c98
-rw-r--r--gnu/usr.bin/cvs/src/rcscmds.c120
-rw-r--r--gnu/usr.bin/cvs/src/server.c3300
-rw-r--r--gnu/usr.bin/cvs/src/update.c927
21 files changed, 4819 insertions, 7297 deletions
diff --git a/gnu/usr.bin/cvs/Makefile.in b/gnu/usr.bin/cvs/Makefile.in
index a66311c9762..18672035f86 100644
--- a/gnu/usr.bin/cvs/Makefile.in
+++ b/gnu/usr.bin/cvs/Makefile.in
@@ -90,35 +90,37 @@ FLAGS_TO_PASS = \
DISTFILES = \
COPYING COPYING.LIB INSTALL README TODO PROJECTS \
- BUGS MINOR-BUGS FAQ HACKING \
+ BUGS MINOR-BUGS FAQ HACKING TESTS \
+ README.VMS build.com \
ChangeLog NEWS ChangeLog.zoo \
configure configure.in stamp-h.in config.h.in Makefile.in acconfig.h \
cvs-format.el mkinstalldirs install-sh \
cvsnt.mak \
- .cvsignore
+ .cvsignore cvs.spec
### Subdirectories to run make in for the primary targets.
# Unix source subdirs, where we'll want to run lint and etags:
-USOURCE_SUBDIRS = lib src
+USOURCE_SUBDIRS = lib zlib src
# Documentation directories; special handling
INSTALL_MAN=man
# All other subdirs:
-SUBDIRS = ${USOURCE_SUBDIRS} ${INSTALL_MAN} doc contrib tools windows-NT os2 macintosh
-# Only make TAGS/tags files in these directories, in this order
-# [Why in this order? If we didn't have to stick to this order, we
-# could make "TSUBDIRS = ${USOURCE_SUBDIRS}". -Karl]
+SUBDIRS = ${USOURCE_SUBDIRS} ${INSTALL_MAN} doc contrib tools \
+ windows-NT os2 macintosh vms
+# Only make TAGS/tags files in these directories.
TSUBDIRS= src lib
# Set default target.
all:
-.PHONY: all install uninstall
-all install uninstall: config.h Makefile all-local
+.PHONY: all install uninstall installdirs
+all install uninstall installdirs: config.h Makefile all-local
@for subdir in $(SUBDIRS); do \
echo "making $@ in $$subdir"; \
( cd $$subdir && $(MAKE) $(FLAGS_TO_PASS) $@ ) || exit 1; \
done
+installdirs: installdirs-local
+
install: all install-local install-info
.PHONY: all-local
@@ -132,6 +134,10 @@ info dvi clean-info install-info:
install-local: all-local
@: nothing to do locally
+.PHONY: installdirs-local
+installdirs-local: all-local
+ @: nothing to do locally
+
.PHONY: tags
tags:
@for dir in $(TSUBDIRS); do echo making $@ in $$dir; cd $$dir && $(MAKE) $(FLAGS_TO_PASS) $@ || exit 1; cd ..; done
@@ -189,16 +195,19 @@ saber:
.PHONY: check
check:
cd lib ; $(MAKE) $(FLAGS_TO_PASS)
+ cd zlib ; $(MAKE) $(FLAGS_TO_PASS)
cd src ; $(MAKE) $(FLAGS_TO_PASS) check
.PHONY: remotecheck
remotecheck:
cd lib ; $(MAKE) $(FLAGS_TO_PASS)
+ cd zlib ; $(MAKE) $(FLAGS_TO_PASS)
cd src ; $(MAKE) $(FLAGS_TO_PASS) remotecheck
.PHONY: installcheck
installcheck:
cd lib ; $(MAKE) $(FLAGS_TO_PASS)
+ cd zlib ; $(MAKE) $(FLAGS_TO_PASS)
cd src ; $(MAKE) $(FLAGS_TO_PASS) installcheck
.PHONY: lint
@@ -209,12 +218,7 @@ lint:
GZIP=gzip --best
GZIP_EXT=.gz
TAR_VERBOSE=
-dist:
- echo > .fname \
- cvs-`sed < $(srcdir)/src/version.c \
- -e '/version_string/!d' \
- -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
- -e q`
+dist: spec
rm -rf `cat .fname`
${MAKE} dist-dir DISTDIR="`cat .fname`"
for dir in ${SUBDIRS}; do \
@@ -224,7 +228,7 @@ dist:
); \
done
tar chf${TAR_VERBOSE} - `cat .fname` | ${GZIP} > "`cat .fname`.tar${GZIP_EXT}"
- rm -rf `cat .fname` .fname
+ rm -rf `cat .fname` .fname .version
.PHONY: dist-dir
dist-dir:
@@ -233,12 +237,31 @@ dist-dir:
ln $(srcdir)/$${i} ${DISTDIR}; \
done
+.PHONY: spec
+spec:
+ rm -f .version .fname
+ sed < $(srcdir)/src/version.c \
+ -e '/version_string/!d' \
+ -e 's/[^0-9.]*\([0-9.]*\).*/\1/' \
+ -e q > .version
+ echo > .fname cvs-`cat .version`
+ rm -f `cat .fname`.spec
+ sed < $(top_srcdir)/cvs.spec \
+ -e 's/@VERSION@/'`cat .version`'/' \
+ > `cat .fname`.spec
+
+
# For the justification of the following Makefile rules, see node
# `Automatic Remaking' in GNU Autoconf documentation.
Makefile: Makefile.in config.status
CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+
+# Use @CFLAGS@ not $(CFLAGS) because it would be confusing for "make CFLAGS="
+# to sometimes (i.e., if configure is modified) change the configured CFLAGS,
+# and sometimes not.
config.status: configure
- ./config.status --recheck
+ CFLAGS="@CFLAGS@" ./config.status --recheck
+
# The rules to run autoconf and autoheader are commented out. This is because
# when the user unpacks a tarfile, configure.in might end up newer than
# configure, but the user might not have (and does not need to have) autoconf
diff --git a/gnu/usr.bin/cvs/configure b/gnu/usr.bin/cvs/configure
index 3025eefa4ea..5518769a39b 100644
--- a/gnu/usr.bin/cvs/configure
+++ b/gnu/usr.bin/cvs/configure
@@ -1,7 +1,7 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.9
+# Generated automatically using autoconf version 2.10
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
@@ -13,6 +13,8 @@ ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
--with-krb4=value set default \$(KRB4) from value"
+ac_help="$ac_help
+ --enable-encryption enable encryption support"
# Initialize some variables set by options.
# The variables have the same names as the options, with
@@ -332,7 +334,7 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.9"
+ echo "configure generated by autoconf version 2.10"
exit 0 ;;
-with-* | --with-*)
@@ -602,7 +604,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:606: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:608: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -655,13 +657,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 659 "configure"
+#line 661 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:665: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:667: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@@ -670,13 +672,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 674 "configure"
+#line 676 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:680: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:682: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@@ -698,7 +700,7 @@ echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for AIX""... $ac_c" 1>&6
cat > conftest.$ac_ext <<EOF
-#line 702 "configure"
+#line 704 "configure"
#include "confdefs.h"
#ifdef _AIX
yes
@@ -725,12 +727,12 @@ 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 729 "configure"
+#line 731 "configure"
#include "confdefs.h"
#include <minix/config.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:734: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:736: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -787,6 +789,7 @@ fi
if test "$ISC" = yes; then
CFLAGS="$CFLAGS -D_SYSV3"
+LIBS="-lcrypt $LIBS"
fi
if test "x$prefix" = xNONE; then
@@ -836,11 +839,11 @@ else
ac_cv_c_cross=yes
else
cat > conftest.$ac_ext <<EOF
-#line 840 "configure"
+#line 843 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-{ (eval echo configure:844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
+{ (eval echo configure:847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ac_cv_c_cross=no
else
@@ -859,7 +862,7 @@ if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 863 "configure"
+#line 866 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -909,7 +912,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
-if { (eval echo configure:913: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:916: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -928,102 +931,6 @@ EOF
fi
-echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$GCC" = yes; then
- # GCC predefines this symbol on systems where it applies.
-cat > conftest.$ac_ext <<EOF
-#line 939 "configure"
-#include "confdefs.h"
-#ifdef __CHAR_UNSIGNED__
- yes
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "yes" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_c_char_unsigned=yes
-else
- rm -rf conftest*
- ac_cv_c_char_unsigned=no
-fi
-rm -f conftest*
-
-else
-if test "$cross_compiling" = yes; then
- { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
-else
-cat > conftest.$ac_ext <<EOF
-#line 961 "configure"
-#include "confdefs.h"
-/* volatile prevents gcc2 from optimizing the test away on sparcs. */
-#if !defined(__STDC__) || __STDC__ != 1
-#define volatile
-#endif
-main() {
- volatile char c = 255; exit(c < 0);
-}
-EOF
-{ (eval echo configure:971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- ac_cv_c_char_unsigned=yes
-else
- ac_cv_c_char_unsigned=no
-fi
-fi
-rm -fr conftest*
-fi
-fi
-
-echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6
-if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
- cat >> confdefs.h <<\EOF
-#define __CHAR_UNSIGNED__ 1
-EOF
-
-fi
-
-echo $ac_n "checking for inline""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_cv_c_inline=no
-for ac_kw in inline __inline__ __inline; do
- cat > conftest.$ac_ext <<EOF
-#line 997 "configure"
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() {
-} $ac_kw foo() {
-; return 0; }
-EOF
-if { (eval echo configure:1005: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_c_inline=$ac_kw; break
-fi
-rm -f conftest*
-
-done
-
-fi
-
-echo "$ac_t""$ac_cv_c_inline" 1>&6
-case "$ac_cv_c_inline" in
- inline | yes) ;;
- no) cat >> confdefs.h <<\EOF
-#define inline
-EOF
- ;;
- *) cat >> confdefs.h <<EOF
-#define inline $ac_cv_c_inline
-EOF
- ;;
-esac
-
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
@@ -1286,7 +1193,7 @@ if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1290 "configure"
+#line 1197 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1294,7 +1201,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1298: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1205: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1309,7 +1216,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1313 "configure"
+#line 1220 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1327,7 +1234,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1331 "configure"
+#line 1238 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1348,7 +1255,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 1352 "configure"
+#line 1259 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1359,7 +1266,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-{ (eval echo configure:1363: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
+{ (eval echo configure:1270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
:
else
@@ -1388,12 +1295,12 @@ 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 1392 "configure"
+#line 1299 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1397: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1304: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -1422,7 +1329,7 @@ if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1426 "configure"
+#line 1333 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
@@ -1439,7 +1346,7 @@ wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:1443: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1350: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
@@ -1463,7 +1370,7 @@ if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1467 "configure"
+#line 1374 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -1518,7 +1425,7 @@ if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1522 "configure"
+#line 1429 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1528,7 +1435,7 @@ int t() {
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1532: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1439: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
@@ -1556,7 +1463,7 @@ if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1560 "configure"
+#line 1467 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_hdr>
@@ -1565,7 +1472,7 @@ int t() {
DIR *dirp = 0;
; return 0; }
EOF
-if { (eval echo configure:1569: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1476: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_header_dirent_$ac_safe=yes"
else
@@ -1589,16 +1496,18 @@ done
# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
if test $ac_header_dirent = dirent.h; then
echo $ac_n "checking for -ldir""... $ac_c" 1>&6
-ac_lib_var=`echo dir_opendir | tr '.-/+' '___p'`
+ac_lib_var=`echo dir'_'opendir | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1600 "configure"
+#line 1507 "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
+ builtin and then its argument prototype would still apply. */
char opendir();
int main() { return 0; }
@@ -1606,7 +1515,7 @@ int t() {
opendir()
; return 0; }
EOF
-if { (eval echo configure:1610: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1519: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1626,16 +1535,18 @@ fi
else
echo $ac_n "checking for -lx""... $ac_c" 1>&6
-ac_lib_var=`echo x_opendir | tr '.-/+' '___p'`
+ac_lib_var=`echo x'_'opendir | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1637 "configure"
+#line 1546 "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
+ builtin and then its argument prototype would still apply. */
char opendir();
int main() { return 0; }
@@ -1643,7 +1554,7 @@ int t() {
opendir()
; return 0; }
EOF
-if { (eval echo configure:1647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1558: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1668,7 +1579,7 @@ if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1672 "configure"
+#line 1583 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
@@ -1686,7 +1597,7 @@ int t() {
int i;
; return 0; }
EOF
-if { (eval echo configure:1690: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1601: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
@@ -1708,7 +1619,7 @@ if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1712 "configure"
+#line 1623 "configure"
#include "confdefs.h"
#include <sys/types.h>
EOF
@@ -1741,7 +1652,7 @@ if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1745 "configure"
+#line 1656 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1772,7 +1683,7 @@ if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1776 "configure"
+#line 1687 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1803,7 +1714,7 @@ if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1807 "configure"
+#line 1718 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -1829,19 +1740,21 @@ EOF
fi
-for ac_func in getwd mkdir rename strdup strstr dup2 strerror valloc waitpid memmove vasprintf strtoul
+for ac_func in getwd mkdir rename strdup strstr dup2 strerror valloc waitpid vasprintf strtoul
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
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 1840 "configure"
+#line 1751 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char $ac_func();
int main() { return 0; }
@@ -1858,7 +1771,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1862: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1775: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1885,12 +1798,14 @@ 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 1889 "configure"
+#line 1802 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char $ac_func();
int main() { return 0; }
@@ -1907,7 +1822,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:1911: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1826: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -1929,17 +1844,126 @@ else
fi
done
+
+echo $ac_n "checking for evidence of shadow passwords""... $ac_c" 1>&6
+if test -f /etc/shadow \
+ || test -f /etc/security/passwd.adjunct \
+ || test -d /etc/security ; then
+ echo "yup"
+ echo $ac_n "checking for -lsec""... $ac_c" 1>&6
+ac_lib_var=`echo sec'_'getspnam | tr './+\055' '__p_'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsec $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1862 "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
+ builtin and then its argument prototype would still apply. */
+char getspnam();
+
+int main() { return 0; }
+int t() {
+getspnam()
+; return 0; }
+EOF
+if { (eval echo configure:1874: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo sec | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lsec $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ for ac_func in getspnam
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+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 1905 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+else
+ echo "nope"
+fi
+
echo $ac_n "checking for re_exec""... $ac_c" 1>&6
if eval "test \"`echo '$''{'ac_cv_func_re_exec'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1938 "configure"
+#line 1960 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char re_exec(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char re_exec();
int main() { return 0; }
@@ -1956,7 +1980,7 @@ re_exec();
; return 0; }
EOF
-if { (eval echo configure:1960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:1984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_re_exec=yes"
else
@@ -1984,7 +2008,7 @@ if test "$cross_compiling" = yes; then
ac_cv_func_utime_null=no
else
cat > conftest.$ac_ext <<EOF
-#line 1988 "configure"
+#line 2012 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -1995,7 +2019,7 @@ exit(!(stat ("conftestdata", &s) == 0 && utime("conftestdata", (long *)0) == 0
&& t.st_mtime - s.st_mtime < 120));
}
EOF
-{ (eval echo configure:1999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
+{ (eval echo configure:2023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ac_cv_func_utime_null=yes
else
@@ -2059,7 +2083,7 @@ else
ccvs_cv_sys_working_fnmatch=no
else
cat > conftest.$ac_ext <<EOF
-#line 2063 "configure"
+#line 2087 "configure"
#include "confdefs.h"
#include <fnmatch.h>
@@ -2071,7 +2095,7 @@ main ()
? 0 : 1);
}
EOF
-{ (eval echo configure:2075: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
+{ (eval echo configure:2099: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ccvs_cv_sys_working_fnmatch=yes
else
@@ -2104,7 +2128,7 @@ else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2108 "configure"
+#line 2132 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -2115,7 +2139,7 @@ main()
exit(0);
}
EOF
-{ (eval echo configure:2119: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
+{ (eval echo configure:2143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ac_cv_sizeof_long=`cat conftestval`
else
@@ -2138,7 +2162,7 @@ else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2142 "configure"
+#line 2166 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -2149,7 +2173,7 @@ main()
exit(0);
}
EOF
-{ (eval echo configure:2153: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
+{ (eval echo configure:2177: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
if test -s conftest && (./conftest; exit) 2>/dev/null; then
ac_cv_sizeof_int=`cat conftestval`
else
@@ -2168,7 +2192,7 @@ EOF
krb_h=
echo $ac_n "checking for krb.h""... $ac_c" 1>&6
cat > conftest.$ac_ext <<EOF
-#line 2172 "configure"
+#line 2196 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@@ -2176,7 +2200,7 @@ int t() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2180: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2204: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=
else
@@ -2185,7 +2209,7 @@ else
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -I$KRB4/include"
cat > conftest.$ac_ext <<EOF
-#line 2189 "configure"
+#line 2213 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@@ -2193,7 +2217,7 @@ int t() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2221: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=$KRB4/include
fi
@@ -2206,7 +2230,7 @@ rm -f conftest*
if test -z "$krb_h"; then
cat > conftest.$ac_ext <<EOF
-#line 2210 "configure"
+#line 2234 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@@ -2214,7 +2238,7 @@ int t() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=
else
@@ -2223,7 +2247,7 @@ else
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -I$KRB4/include/kerberosIV"
cat > conftest.$ac_ext <<EOF
-#line 2227 "configure"
+#line 2251 "configure"
#include "confdefs.h"
#include <krb.h>
int main() { return 0; }
@@ -2231,7 +2255,7 @@ int t() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2235: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
krb_h=yes krb_incdir=$KRB4/include/kerberosIV
fi
@@ -2248,16 +2272,18 @@ echo "$ac_t""$krb_h" 1>&6
if test -n "$krb_h"; then
krb_lib=
echo $ac_n "checking for -lkrb""... $ac_c" 1>&6
-ac_lib_var=`echo krb_printf | tr '.-/+' '___p'`
+ac_lib_var=`echo krb'_'printf | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lkrb $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2259 "configure"
+#line 2283 "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
+ builtin and then its argument prototype would still apply. */
char printf();
int main() { return 0; }
@@ -2265,7 +2291,7 @@ int t() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2293,17 +2319,24 @@ EOF
test -n "${krb_libdir}" && LIBS="${LIBS} -L${krb_libdir}"
LIBS="${LIBS} -lkrb"
+ # Put -L${krb_libdir} in LDFLAGS temporarily so that it appears before
+ # -ldes in the command line. Don't do it permanently so that we honor
+ # the user's setting for LDFLAGS
+ hold_ldflags=$LDFLAGS
+ test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}"
echo $ac_n "checking for -ldes""... $ac_c" 1>&6
-ac_lib_var=`echo des_printf | tr '.-/+' '___p'`
+ac_lib_var=`echo des'_'printf | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-ldes $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2305 "configure"
+#line 2336 "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
+ builtin and then its argument prototype would still apply. */
char printf();
int main() { return 0; }
@@ -2311,7 +2344,7 @@ int t() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2348: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2329,6 +2362,7 @@ else
echo "$ac_t""no" 1>&6
fi
+ LDFLAGS=$hold_ldflags
if test -n "$krb_incdir"; then
includeopt="${includeopt} -I$krb_incdir"
@@ -2342,12 +2376,14 @@ 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 2346 "configure"
+#line 2380 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char $ac_func();
int main() { return 0; }
@@ -2364,7 +2400,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -2386,6 +2422,26 @@ else
fi
done
+
+# Check whether --enable-encryption or --disable-encryption was given.
+if test "${enable_encryption+set}" = set; then
+ enableval="$enable_encryption"
+ case "${enableval}" in
+ yes) encryption=true ;;
+ no) encryption=false ;;
+ *) { echo "configure: error: bad value ${enableval} for encryption option" 1>&2; exit 1; } ;;
+ esac
+else
+ encryption=false
+fi
+
+if test "$encryption" = "true"; then
+ cat >> confdefs.h <<\EOF
+#define ENCRYPTION 1
+EOF
+
+fi
+
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
# libsocket.so which has a bad implementation of gethostbyname (it
@@ -2397,12 +2453,14 @@ 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 2401 "configure"
+#line 2457 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char connect(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char connect();
int main() { return 0; }
@@ -2419,7 +2477,7 @@ connect();
; return 0; }
EOF
-if { (eval echo configure:2423: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_connect=yes"
else
@@ -2437,16 +2495,18 @@ else
case "$LIBS" in
*-lnsl*) ;;
*) echo $ac_n "checking for -lnsl_s""... $ac_c" 1>&6
-ac_lib_var=`echo nsl_s_printf | tr '.-/+' '___p'`
+ac_lib_var=`echo nsl_s'_'printf | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lnsl_s $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2448 "configure"
+#line 2506 "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
+ builtin and then its argument prototype would still apply. */
char printf();
int main() { return 0; }
@@ -2454,7 +2514,7 @@ int t() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2518: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2482,16 +2542,18 @@ esac
case "$LIBS" in
*-lnsl*) ;;
*) echo $ac_n "checking for -lnsl""... $ac_c" 1>&6
-ac_lib_var=`echo nsl_printf | tr '.-/+' '___p'`
+ac_lib_var=`echo nsl'_'printf | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2493 "configure"
+#line 2553 "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
+ builtin and then its argument prototype would still apply. */
char printf();
int main() { return 0; }
@@ -2499,7 +2561,7 @@ int t() {
printf()
; return 0; }
EOF
-if { (eval echo configure:2503: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2527,16 +2589,18 @@ esac
case "$LIBS" in
*-lsocket*) ;;
*) echo $ac_n "checking for -lsocket""... $ac_c" 1>&6
-ac_lib_var=`echo socket_connect | tr '.-/+' '___p'`
+ac_lib_var=`echo socket'_'connect | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2538 "configure"
+#line 2600 "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
+ builtin and then its argument prototype would still apply. */
char connect();
int main() { return 0; }
@@ -2544,7 +2608,7 @@ int t() {
connect()
; return 0; }
EOF
-if { (eval echo configure:2548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2572,16 +2636,18 @@ esac
case "$LIBS" in
*-linet*) ;;
*) echo $ac_n "checking for -linet""... $ac_c" 1>&6
-ac_lib_var=`echo inet_connect | tr '.-/+' '___p'`
+ac_lib_var=`echo inet'_'connect | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-linet $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2583 "configure"
+#line 2647 "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
+ builtin and then its argument prototype would still apply. */
char connect();
int main() { return 0; }
@@ -2589,7 +2655,7 @@ int t() {
connect()
; return 0; }
EOF
-if { (eval echo configure:2593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2659: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2622,12 +2688,14 @@ 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 2626 "configure"
+#line 2692 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char $ac_func();
int main() { return 0; }
@@ -2644,7 +2712,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2716: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -2674,12 +2742,14 @@ 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 2678 "configure"
+#line 2746 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char gethostname(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char gethostname();
int main() { return 0; }
@@ -2696,7 +2766,7 @@ gethostname();
; return 0; }
EOF
-if { (eval echo configure:2700: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2770: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_gethostname=yes"
else
@@ -2732,12 +2802,14 @@ if eval "test \"`echo '$''{'ac_cv_func_crypt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2736 "configure"
+#line 2806 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char crypt(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char crypt();
int main() { return 0; }
@@ -2754,7 +2826,7 @@ crypt();
; return 0; }
EOF
-if { (eval echo configure:2758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_crypt=yes"
else
@@ -2772,16 +2844,18 @@ else
case "$LIBS" in
*-lcrypt*) ;;
*) echo $ac_n "checking for -lcrypt""... $ac_c" 1>&6
-ac_lib_var=`echo crypt_crypt | tr '.-/+' '___p'`
+ac_lib_var=`echo crypt'_'crypt | tr './+\055' '__p_'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 2783 "configure"
+#line 2855 "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
+ builtin and then its argument prototype would still apply. */
char crypt();
int main() { return 0; }
@@ -2789,7 +2863,7 @@ int t() {
crypt()
; return 0; }
EOF
-if { (eval echo configure:2793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -2822,12 +2896,14 @@ 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 2826 "configure"
+#line 2900 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
#include <assert.h>
/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
char $ac_func();
int main() { return 0; }
@@ -2844,7 +2920,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2848: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+if { (eval echo configure:2924: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -2959,7 +3035,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.9"
+ echo "$CONFIG_STATUS generated by autoconf version 2.10"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -2970,10 +3046,11 @@ done
ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
-trap 'rm -fr `echo "Makefile lib/Makefile src/Makefile doc/Makefile \
+trap 'rm -fr `echo "Makefile lib/Makefile src/Makefile zlib/Makefile doc/Makefile \
man/Makefile tools/Makefile tools/pcl-cvs/Makefile \
contrib/Makefile contrib/elib/Makefile \
- windows-NT/Makefile os2/Makefile macintosh/Makefile stamp-h config.h src/options.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+ windows-NT/Makefile os2/Makefile macintosh/Makefile vms/Makefile \
+ stamp-h config.h src/options.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
@@ -3021,10 +3098,11 @@ CEOF
EOF
cat >> $CONFIG_STATUS <<EOF
-CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile src/Makefile doc/Makefile \
+CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile src/Makefile zlib/Makefile doc/Makefile \
man/Makefile tools/Makefile tools/pcl-cvs/Makefile \
contrib/Makefile contrib/elib/Makefile \
- windows-NT/Makefile os2/Makefile macintosh/Makefile stamp-h"}
+ windows-NT/Makefile os2/Makefile macintosh/Makefile vms/Makefile \
+ stamp-h"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
@@ -3171,6 +3249,12 @@ cat >> $CONFIG_STATUS <<\EOF
echo "$ac_file is unchanged"
rm -f conftest.h
else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
rm -f $ac_file
mv conftest.h $ac_file
fi
diff --git a/gnu/usr.bin/cvs/configure.in b/gnu/usr.bin/cvs/configure.in
index 554a401fa6a..e7d3d52491f 100644
--- a/gnu/usr.bin/cvs/configure.in
+++ b/gnu/usr.bin/cvs/configure.in
@@ -11,6 +11,7 @@ AC_MINIX
AC_ISC_POSIX
if test "$ISC" = yes; then
CFLAGS="$CFLAGS -D_SYSV3"
+LIBS="-lcrypt $LIBS"
fi
AC_PREFIX_PROGRAM(cvs)
@@ -18,8 +19,6 @@ AC_PREFIX_PROGRAM(cvs)
AC_C_CROSS
AC_C_CONST
-AC_C_CHAR_UNSIGNED
-AC_C_INLINE
AC_PROG_INSTALL
AC_PROG_RANLIB
@@ -49,8 +48,25 @@ AC_TYPE_UID_T
AC_TYPE_MODE_T
AC_TYPE_SIZE_T
AC_TYPE_PID_T
-AC_REPLACE_FUNCS(getwd mkdir rename strdup strstr dup2 strerror valloc waitpid memmove vasprintf strtoul)
+AC_REPLACE_FUNCS(getwd mkdir rename strdup strstr dup2 strerror valloc waitpid vasprintf strtoul)
AC_CHECK_FUNCS(fchmod fsync ftime mkfifo putenv setvbuf vfork vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock)
+
+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
+AC_MSG_CHECKING([for evidence of shadow passwords])
+if test -f /etc/shadow \
+ || test -f /etc/security/passwd.adjunct \
+ || test -d /etc/security ; then
+ echo "yup"
+ AC_CHECK_LIB(sec, getspnam)
+ AC_CHECK_FUNCS(getspnam)
+else
+ echo "nope"
+fi
+
AC_CHECK_FUNC(re_exec, :, LIBOBJS="$LIBOBJS regex.o")
AC_FUNC_UTIME_NULL
AC_SYS_LONG_FILE_NAMES
@@ -124,7 +140,13 @@ if test -n "$krb_h"; then
AC_DEFINE(HAVE_KERBEROS)
test -n "${krb_libdir}" && LIBS="${LIBS} -L${krb_libdir}"
LIBS="${LIBS} -lkrb"
+ # Put -L${krb_libdir} in LDFLAGS temporarily so that it appears before
+ # -ldes in the command line. Don't do it permanently so that we honor
+ # the user's setting for LDFLAGS
+ hold_ldflags=$LDFLAGS
+ test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}"
AC_CHECK_LIB(des,printf,[LIBS="${LIBS} -ldes"])
+ LDFLAGS=$hold_ldflags
if test -n "$krb_incdir"; then
includeopt="${includeopt} -I$krb_incdir"
AC_SUBST(includeopt)
@@ -132,6 +154,22 @@ if test -n "$krb_h"; then
fi
fi
AC_CHECK_FUNCS(krb_get_err_text)
+
+dnl
+dnl Use --with-encryption to turn on encryption support
+dnl
+AC_ARG_ENABLE(encryption,
+ [ --enable-encryption enable encryption support],
+ [case "${enableval}" in
+ yes) encryption=true ;;
+ no) encryption=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for encryption option) ;;
+ esac],
+ [encryption=false])
+if test "$encryption" = "true"; then
+ AC_DEFINE(ENCRYPTION)
+fi
+
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
# libsocket.so which has a bad implementation of gethostbyname (it
@@ -185,7 +223,8 @@ test -f src/options.h && (
cp ./src/options.h ./src/options.h-SAVED
)
-AC_OUTPUT(Makefile lib/Makefile src/Makefile doc/Makefile \
+AC_OUTPUT(Makefile lib/Makefile src/Makefile zlib/Makefile doc/Makefile \
man/Makefile tools/Makefile tools/pcl-cvs/Makefile \
contrib/Makefile contrib/elib/Makefile \
- windows-NT/Makefile os2/Makefile macintosh/Makefile stamp-h)
+ windows-NT/Makefile os2/Makefile macintosh/Makefile vms/Makefile \
+ stamp-h)
diff --git a/gnu/usr.bin/cvs/contrib/Makefile.in b/gnu/usr.bin/cvs/contrib/Makefile.in
index 7db15fbd18b..8292b9dded1 100644
--- a/gnu/usr.bin/cvs/contrib/Makefile.in
+++ b/gnu/usr.bin/cvs/contrib/Makefile.in
@@ -84,7 +84,7 @@ CONTRIB_PROGS = clmerge cln_hist commit_prep cvs_acls cvscheck log log_accum \
all: Makefile $(PROGS) $(CONTRIB_PROGS)
.PHONY: all
-install: all $(libdir)/cvs/contrib
+install: all installdirs
for f in $(CONTRIB_FILES) ; do\
$(INSTALL_DATA) $(srcdir)/$$f $(libdir)/cvs/contrib/$$f; \
done
@@ -94,11 +94,11 @@ install: all $(libdir)/cvs/contrib
for f in $(PROGS) ; do\
$(INSTALL_PROGRAM) $$f $(bindir)/$$f; \
done
- @echo "You might consider running 'cvsinit' to upgrade your repository(s)...."
.PHONY: install
-$(libdir)/cvs/contrib:
+installdirs:
$(SHELL) $(top_srcdir)/mkinstalldirs $(libdir)/cvs/contrib
+.PHONY: installdirs
tags:
.PHONY: tags
diff --git a/gnu/usr.bin/cvs/lib/getdate.c b/gnu/usr.bin/cvs/lib/getdate.c
index 20f442f1ceb..77da8b87a42 100644
--- a/gnu/usr.bin/cvs/lib/getdate.c
+++ b/gnu/usr.bin/cvs/lib/getdate.c
@@ -1,26 +1,14 @@
-
-/* A Bison parser, made from ./getdate.y
- by Bison version A2.5 (Andrew Consortium)
- */
-
-#define YYBISON 1 /* Identify Bison output. */
-
-#define tAGO 258
-#define tDAY 259
-#define tDAYZONE 260
-#define tID 261
-#define tMERIDIAN 262
-#define tMINUTE_UNIT 263
-#define tMONTH 264
-#define tMONTH_UNIT 265
-#define tSEC_UNIT 266
-#define tSNUMBER 267
-#define tUNUMBER 268
-#define tZONE 269
-#define tDST 270
-
-#line 1 "./getdate.y"
-
+#ifndef lint
+static char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
+#endif
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+#define yyclearin (yychar=(-1))
+#define yyerrok (yyerrflag=0)
+#define YYRECOVERING (yyerrflag!=0)
+#define YYPREFIX "yy"
+#line 2 "../../lib/getdate.y"
/*
** Originally written by Steven M. Bellovin <smb@research.att.com> while
** at the University of North Carolina at Chapel Hill. Later tweaked by
@@ -118,9 +106,18 @@ struct timeb {
#include <stdlib.h>
#endif
-#if defined (HAVE_ALLOCA_H)
-#include <alloca.h>
-#endif
+/* NOTES on rebuilding getdate.c (particularly for inclusion in CVS
+ releases):
+
+ We don't want to mess with all the portability hassles of alloca.
+ In particular, most (all?) versions of bison will use alloca in
+ their parser. If bison works on your system (e.g. it should work
+ with gcc), then go ahead and use it, but the more general solution
+ is to use byacc instead of bison, which should generate a portable
+ parser. I played with adding "#define alloca dont_use_alloca", to
+ give an error if the parser generator uses alloca (and thus detect
+ unportable getdate.c's), but that seems to cause as many problems
+ as it solves. */
extern struct tm *gmtime();
extern struct tm *localtime();
@@ -129,10 +126,6 @@ extern struct tm *localtime();
#define yylex getdate_yylex
#define yyerror getdate_yyerror
-#if !defined(lint) && !defined(SABER)
-static char RCS[] = "$CVSid: @(#)getdate.y 1.11 94/09/21 $";
-#endif /* !defined(lint) && !defined(SABER) */
-
static int yylex ();
static int yyerror ();
@@ -192,1142 +185,225 @@ static MERIDIAN yyMeridian;
static time_t yyRelMonth;
static time_t yyRelSeconds;
-
-#line 175 "./getdate.y"
+#line 180 "../../lib/getdate.y"
typedef union {
time_t Number;
enum _MERIDIAN Meridian;
} YYSTYPE;
-#include <stdio.h>
-
-#ifndef __cplusplus
-#ifndef __STDC__
-#define const
-#endif
-#endif
-
-
-
-#define YYFINAL 52
-#define YYFLAG -32768
-#define YYNTBASE 19
-
-#define YYTRANSLATE(x) ((unsigned)(x) <= 270 ? yytranslate[x] : 29)
-
-static const char yytranslate[] = { 0,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 17, 2, 2, 18, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 16, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-
-#if YYDEBUG != 0
-static const short yyprhs[] = { 0,
- 0, 1, 4, 6, 8, 10, 12, 14, 16, 19,
- 24, 29, 36, 43, 45, 47, 50, 52, 55, 58,
- 62, 68, 72, 76, 79, 84, 87, 91, 94, 96,
- 99, 102, 104, 107, 110, 112, 115, 118, 120, 122,
- 123
-};
-
-static const short yyrhs[] = { -1,
- 19, 20, 0, 21, 0, 22, 0, 24, 0, 23,
- 0, 25, 0, 27, 0, 13, 7, 0, 13, 16,
- 13, 28, 0, 13, 16, 13, 12, 0, 13, 16,
- 13, 16, 13, 28, 0, 13, 16, 13, 16, 13,
- 12, 0, 14, 0, 5, 0, 14, 15, 0, 4,
- 0, 4, 17, 0, 13, 4, 0, 13, 18, 13,
- 0, 13, 18, 13, 18, 13, 0, 13, 12, 12,
- 0, 13, 9, 12, 0, 9, 13, 0, 9, 13,
- 17, 13, 0, 13, 9, 0, 13, 9, 13, 0,
- 26, 3, 0, 26, 0, 13, 8, 0, 12, 8,
- 0, 8, 0, 12, 11, 0, 13, 11, 0, 11,
- 0, 12, 10, 0, 13, 10, 0, 10, 0, 13,
- 0, 0, 7, 0
+#line 194 "y.tab.c"
+#define tAGO 257
+#define tDAY 258
+#define tDAYZONE 259
+#define tID 260
+#define tMERIDIAN 261
+#define tMINUTE_UNIT 262
+#define tMONTH 263
+#define tMONTH_UNIT 264
+#define tSEC_UNIT 265
+#define tSNUMBER 266
+#define tUNUMBER 267
+#define tZONE 268
+#define tDST 269
+#define YYERRCODE 256
+short yylhs[] = { -1,
+ 0, 0, 2, 2, 2, 2, 2, 2, 3, 3,
+ 3, 3, 3, 4, 4, 4, 6, 6, 6, 5,
+ 5, 5, 5, 5, 5, 5, 5, 7, 7, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 8, 1,
+ 1,
};
-
-#endif
-
-#if YYDEBUG != 0
-static const short yyrline[] = { 0,
- 189, 190, 193, 196, 199, 202, 205, 208, 211, 217,
- 223, 230, 236, 246, 250, 254, 261, 265, 269, 275,
- 279, 284, 290, 296, 300, 305, 309, 316, 320, 323,
- 326, 329, 332, 335, 338, 341, 344, 347, 352, 379,
- 382
+short yylen[] = { 2,
+ 0, 2, 1, 1, 1, 1, 1, 1, 2, 4,
+ 4, 6, 6, 1, 1, 2, 1, 2, 2, 3,
+ 5, 3, 3, 2, 4, 2, 3, 2, 1, 2,
+ 2, 1, 2, 2, 1, 2, 2, 1, 1, 0,
+ 1,
};
-#endif
-
-
-#if YYDEBUG != 0
-
-static const char * const yytname[] = { "$","error","$undefined.","tAGO","tDAY",
-"tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
-"tSNUMBER","tUNUMBER","tZONE","tDST","':'","','","'/'","spec","item","time",
-"zone","day","date","rel","relunit","number","o_merid", NULL
+short yydefred[] = { 1,
+ 0, 0, 15, 32, 0, 38, 35, 0, 0, 0,
+ 2, 3, 4, 5, 6, 7, 8, 0, 18, 0,
+ 31, 36, 33, 19, 9, 30, 0, 37, 34, 0,
+ 0, 0, 16, 28, 0, 23, 27, 22, 0, 0,
+ 25, 41, 11, 0, 10, 0, 0, 21, 13, 12,
};
-#endif
-
-static const short yyr1[] = { 0,
- 19, 19, 20, 20, 20, 20, 20, 20, 21, 21,
- 21, 21, 21, 22, 22, 22, 23, 23, 23, 24,
- 24, 24, 24, 24, 24, 24, 24, 25, 25, 26,
- 26, 26, 26, 26, 26, 26, 26, 26, 27, 28,
- 28
+short yydgoto[] = { 1,
+ 45, 11, 12, 13, 14, 15, 16, 17, 18,
};
-
-static const short yyr2[] = { 0,
- 0, 2, 1, 1, 1, 1, 1, 1, 2, 4,
- 4, 6, 6, 1, 1, 2, 1, 2, 2, 3,
- 5, 3, 3, 2, 4, 2, 3, 2, 1, 2,
- 2, 1, 2, 2, 1, 2, 2, 1, 1, 0,
- 1
+short yysindex[] = { 0,
+ -249, -38, 0, 0, -260, 0, 0, -240, -47, -248,
+ 0, 0, 0, 0, 0, 0, 0, -237, 0, -18,
+ 0, 0, 0, 0, 0, 0, -262, 0, 0, -239,
+ -238, -236, 0, 0, -235, 0, 0, 0, -56, -19,
+ 0, 0, 0, -234, 0, -232, -258, 0, 0, 0,
};
-
-static const short yydefact[] = { 1,
- 0, 17, 15, 32, 0, 38, 35, 0, 39, 14,
- 2, 3, 4, 6, 5, 7, 29, 8, 18, 24,
- 31, 36, 33, 19, 9, 30, 26, 37, 34, 0,
- 0, 0, 16, 28, 0, 23, 27, 22, 40, 20,
- 25, 41, 11, 0, 10, 0, 40, 21, 13, 12,
- 0, 0
+short yyrindex[] = { 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 69, 12,
+ 0, 0, 0, 0, 0, 0, 0, 23, 0, 34,
+ 0, 0, 0, 0, 0, 0, 67, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 56, 45,
+ 0, 0, 0, 0, 0, 0, 56, 0, 0, 0,
};
-
-static const short yydefgoto[] = { 1,
- 11, 12, 13, 14, 15, 16, 17, 18, 45
+short yygindex[] = { 0,
+ -17, 0, 0, 0, 0, 0, 0, 0, 0,
};
-
-static const short yypact[] = {-32768,
- 0, -1,-32768,-32768, 4,-32768,-32768, 25, 11, -8,
--32768,-32768,-32768,-32768,-32768,-32768, 21,-32768,-32768, 9,
--32768,-32768,-32768,-32768,-32768,-32768, -10,-32768,-32768, 16,
- 19, 24,-32768,-32768, 26,-32768,-32768,-32768, 18, 13,
--32768,-32768,-32768, 27,-32768, 28, -6,-32768,-32768,-32768,
- 38,-32768
-};
-
-static const short yypgoto[] = {-32768,
--32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -5
+#define YYTABLESIZE 337
+short yytable[] = { 32,
+ 17, 44, 42, 36, 37, 19, 20, 49, 2, 3,
+ 31, 14, 4, 5, 6, 7, 8, 9, 10, 34,
+ 33, 21, 29, 22, 23, 35, 38, 46, 39, 50,
+ 40, 41, 47, 24, 48, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 20, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 40, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 26, 0, 39, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 42, 0, 0, 0, 0, 43,
+ 24, 0, 0, 25, 26, 27, 28, 29, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 17, 17,
+ 0, 0, 17, 17, 17, 17, 17, 17, 17, 14,
+ 14, 0, 0, 14, 14, 14, 14, 14, 14, 14,
+ 29, 29, 0, 0, 29, 29, 29, 29, 29, 29,
+ 29, 24, 24, 0, 0, 24, 24, 24, 24, 24,
+ 24, 24, 20, 20, 0, 0, 20, 20, 20, 20,
+ 20, 20, 20, 40, 40, 0, 0, 40, 40, 40,
+ 40, 0, 40, 40, 26, 26, 0, 39, 26, 26,
+ 26, 26, 0, 0, 26, 39, 39,
};
-
-
-#define YYLAST 42
-
-
-static const short yytable[] = { 51,
- 42, 36, 37, 2, 3, 49, 33, 4, 5, 6,
- 7, 8, 9, 10, 24, 19, 20, 25, 26, 27,
- 28, 29, 30, 34, 42, 35, 31, 38, 32, 43,
- 46, 39, 21, 44, 22, 23, 40, 52, 41, 47,
- 48, 50
+short yycheck[] = { 47,
+ 0, 58, 261, 266, 267, 44, 267, 266, 258, 259,
+ 58, 0, 262, 263, 264, 265, 266, 267, 268, 257,
+ 269, 262, 0, 264, 265, 44, 266, 47, 267, 47,
+ 267, 267, 267, 0, 267, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 0, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 0, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, -1, 0, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 261, -1, -1, -1, -1, 266,
+ 258, -1, -1, 261, 262, 263, 264, 265, 266, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 258, 259,
+ -1, -1, 262, 263, 264, 265, 266, 267, 268, 258,
+ 259, -1, -1, 262, 263, 264, 265, 266, 267, 268,
+ 258, 259, -1, -1, 262, 263, 264, 265, 266, 267,
+ 268, 258, 259, -1, -1, 262, 263, 264, 265, 266,
+ 267, 268, 258, 259, -1, -1, 262, 263, 264, 265,
+ 266, 267, 268, 258, 259, -1, -1, 262, 263, 264,
+ 265, -1, 267, 268, 258, 259, -1, 259, 262, 263,
+ 264, 265, -1, -1, 268, 267, 268,
};
-
-static const short yycheck[] = { 0,
- 7, 12, 13, 4, 5, 12, 15, 8, 9, 10,
- 11, 12, 13, 14, 4, 17, 13, 7, 8, 9,
- 10, 11, 12, 3, 7, 17, 16, 12, 18, 12,
- 18, 13, 8, 16, 10, 11, 13, 0, 13, 13,
- 13, 47
+#define YYFINAL 1
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 269
+#if YYDEBUG
+char *yyname[] = {
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,"','",0,0,"'/'",0,0,0,0,0,0,0,0,0,0,"':'",0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"tAGO","tDAY",
+"tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
+"tSNUMBER","tUNUMBER","tZONE","tDST",
};
-/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/share/bison.simple"
-
-/* Skeleton output parser for bison,
- Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* As a special exception, when this file is copied by Bison into a
- Bison output file, you may use that output file without restriction.
- This special exception was added by the Free Software Foundation
- in version 1.24 of Bison. */
-
-#ifndef alloca
-#ifdef __GNUC__
-#define alloca __builtin_alloca
-#else /* not GNU C. */
-#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
-#include <alloca.h>
-#else /* not sparc */
-#if defined (MSDOS) && !defined (__TURBOC__)
-#include <malloc.h>
-#else /* not MSDOS, or __TURBOC__ */
-#if defined(_AIX)
-#include <malloc.h>
- #pragma alloca
-#else /* not MSDOS, __TURBOC__, or _AIX */
-#ifdef __hpux
-#ifdef __cplusplus
-extern "C" {
-void *alloca (unsigned int);
+char *yyrule[] = {
+"$accept : spec",
+"spec :",
+"spec : spec item",
+"item : time",
+"item : zone",
+"item : date",
+"item : day",
+"item : rel",
+"item : number",
+"time : tUNUMBER tMERIDIAN",
+"time : tUNUMBER ':' tUNUMBER o_merid",
+"time : tUNUMBER ':' tUNUMBER tSNUMBER",
+"time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
+"time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
+"zone : tZONE",
+"zone : tDAYZONE",
+"zone : tZONE tDST",
+"day : tDAY",
+"day : tDAY ','",
+"day : tUNUMBER tDAY",
+"date : tUNUMBER '/' tUNUMBER",
+"date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
+"date : tUNUMBER tSNUMBER tSNUMBER",
+"date : tUNUMBER tMONTH tSNUMBER",
+"date : tMONTH tUNUMBER",
+"date : tMONTH tUNUMBER ',' tUNUMBER",
+"date : tUNUMBER tMONTH",
+"date : tUNUMBER tMONTH tUNUMBER",
+"rel : relunit tAGO",
+"rel : relunit",
+"relunit : tUNUMBER tMINUTE_UNIT",
+"relunit : tSNUMBER tMINUTE_UNIT",
+"relunit : tMINUTE_UNIT",
+"relunit : tSNUMBER tSEC_UNIT",
+"relunit : tUNUMBER tSEC_UNIT",
+"relunit : tSEC_UNIT",
+"relunit : tSNUMBER tMONTH_UNIT",
+"relunit : tUNUMBER tMONTH_UNIT",
+"relunit : tMONTH_UNIT",
+"number : tUNUMBER",
+"o_merid :",
+"o_merid : tMERIDIAN",
};
-#else /* not __cplusplus */
-void *alloca ();
-#endif /* not __cplusplus */
-#endif /* __hpux */
-#endif /* not _AIX */
-#endif /* not MSDOS, or __TURBOC__ */
-#endif /* not sparc. */
-#endif /* not GNU C. */
-#endif /* alloca not defined. */
-
-/* This is the parser code that is written into each bison parser
- when the %semantic_parser declaration is not specified in the grammar.
- It was written by Richard Stallman by simplifying the hairy parser
- used when %semantic_parser is specified. */
-
-/* Note: there must be only one dollar sign in this file.
- It is replaced by the list of actions, each action
- as one case of the switch. */
-
-#define yyerrok (yyerrstatus = 0)
-#define yyclearin (yychar = YYEMPTY)
-#define YYEMPTY -2
-#define YYEOF 0
-#define YYACCEPT return(0)
-#define YYABORT return(1)
-#define YYERROR goto yyerrlab1
-/* Like YYERROR except do call yyerror.
- This remains here temporarily to ease the
- transition to the new meaning of YYERROR, for GCC.
- Once GCC version 2 has supplanted version 1, this can go. */
-#define YYFAIL goto yyerrlab
-#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(token, value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { yychar = (token), yylval = (value); \
- yychar1 = YYTRANSLATE (yychar); \
- YYPOPSTACK; \
- goto yybackup; \
- } \
- else \
- { yyerror ("syntax error: cannot back up"); YYERROR; } \
-while (0)
-
-#define YYTERROR 1
-#define YYERRCODE 256
-
-#ifndef YYPURE
-#define YYLEX yylex()
-#endif
-
-#ifdef YYPURE
-#ifdef YYLSP_NEEDED
-#ifdef YYLEX_PARAM
-#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
-#else
-#define YYLEX yylex(&yylval, &yylloc)
#endif
-#else /* not YYLSP_NEEDED */
-#ifdef YYLEX_PARAM
-#define YYLEX yylex(&yylval, YYLEX_PARAM)
-#else
-#define YYLEX yylex(&yylval)
-#endif
-#endif /* not YYLSP_NEEDED */
-#endif
-
-/* If nonreentrant, generate the variables here */
-
-#ifndef YYPURE
-
-int yychar; /* the lookahead symbol */
-YYSTYPE yylval; /* the semantic value of the */
- /* lookahead symbol */
-
-#ifdef YYLSP_NEEDED
-YYLTYPE yylloc; /* location data for the lookahead */
- /* symbol */
-#endif
-
-int yynerrs; /* number of parse errors so far */
-#endif /* not YYPURE */
-
-#if YYDEBUG != 0
-int yydebug; /* nonzero means print parse trace */
-/* Since this is uninitialized, it does not stop multiple parsers
- from coexisting. */
-#endif
-
-/* YYINITDEPTH indicates the initial size of the parser's stacks */
-
-#ifndef YYINITDEPTH
-#define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH is the maximum size the stacks can grow to
- (effective only if the built-in stack extension method is used). */
-
-#if YYMAXDEPTH == 0
+#ifdef YYSTACKSIZE
#undef YYMAXDEPTH
-#endif
-
-#ifndef YYMAXDEPTH
-#define YYMAXDEPTH 10000
-#endif
-
-/* Prevent warning if -Wstrict-prototypes. */
-#ifdef __GNUC__
-int yyparse (void);
-#endif
-
-#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
-#define __yy_memcpy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)
-#else /* not GNU C or C++ */
-#ifndef __cplusplus
-
-/* This is the most reliable way to avoid incompatibilities
- in available built-in functions on various systems. */
-static void
-__yy_memcpy (from, to, count)
- char *from;
- char *to;
- int count;
-{
- register char *f = from;
- register char *t = to;
- register int i = count;
-
- while (i-- > 0)
- *t++ = *f++;
-}
-
-#else /* __cplusplus */
-
-/* This is the most reliable way to avoid incompatibilities
- in available built-in functions on various systems. */
-static void
-__yy_memcpy (char *from, char *to, int count)
-{
- register char *f = from;
- register char *t = to;
- register int i = count;
-
- while (i-- > 0)
- *t++ = *f++;
-}
-
-#endif
-#endif
-
-#line 192 "/usr/share/bison.simple"
-
-/* The user can define YYPARSE_PARAM as the name of an argument to be passed
- into yyparse. The argument should have type void *.
- It should actually point to an object.
- Grammar actions can access the variable by casting it
- to the proper pointer type. */
-
-#ifdef YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
+#define YYMAXDEPTH YYSTACKSIZE
#else
-#define YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL
-#endif
-
-int
-yyparse(YYPARSE_PARAM)
- YYPARSE_PARAM_DECL
-{
- register int yystate;
- register int yyn;
- register short *yyssp;
- register YYSTYPE *yyvsp;
- int yyerrstatus; /* number of tokens to shift before error messages enabled */
- int yychar1 = 0; /* lookahead token as an internal (translated) token number */
-
- short yyssa[YYINITDEPTH]; /* the state stack */
- YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
-
- short *yyss = yyssa; /* refer to the stacks thru separate pointers */
- YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
-
-#ifdef YYLSP_NEEDED
- YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
- YYLTYPE *yyls = yylsa;
- YYLTYPE *yylsp;
-
-#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
#else
-#define YYPOPSTACK (yyvsp--, yyssp--)
-#endif
-
- int yystacksize = YYINITDEPTH;
-
-#ifdef YYPURE
- int yychar;
- YYSTYPE yylval;
- int yynerrs;
-#ifdef YYLSP_NEEDED
- YYLTYPE yylloc;
-#endif
-#endif
-
- YYSTYPE yyval; /* the variable used to return */
- /* semantic values from the action */
- /* routines */
-
- int yylen;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Starting parse\n");
-#endif
-
- yystate = 0;
- yyerrstatus = 0;
- yynerrs = 0;
- yychar = YYEMPTY; /* Cause a token to be read. */
-
- /* Initialize stack pointers.
- Waste one element of value and location stack
- so that they stay on the same level as the state stack.
- The wasted elements are never initialized. */
-
- yyssp = yyss - 1;
- yyvsp = yyvs;
-#ifdef YYLSP_NEEDED
- yylsp = yyls;
-#endif
-
-/* Push a new state, which is found in yystate . */
-/* In all cases, when you get here, the value and location stacks
- have just been pushed. so pushing a state here evens the stacks. */
-yynewstate:
-
- *++yyssp = yystate;
-
- if (yyssp >= yyss + yystacksize - 1)
- {
- /* Give user a chance to reallocate the stack */
- /* Use copies of these so that the &'s don't force the real ones into memory. */
- YYSTYPE *yyvs1 = yyvs;
- short *yyss1 = yyss;
-#ifdef YYLSP_NEEDED
- YYLTYPE *yyls1 = yyls;
-#endif
-
- /* Get the current used size of the three stacks, in elements. */
- int size = yyssp - yyss + 1;
-
-#ifdef yyoverflow
- /* Each stack pointer address is followed by the size of
- the data in use in that stack, in bytes. */
-#ifdef YYLSP_NEEDED
- /* This used to be a conditional around just the two extra args,
- but that might be undefined if yyoverflow is a macro. */
- yyoverflow("parser stack overflow",
- &yyss1, size * sizeof (*yyssp),
- &yyvs1, size * sizeof (*yyvsp),
- &yyls1, size * sizeof (*yylsp),
- &yystacksize);
-#else
- yyoverflow("parser stack overflow",
- &yyss1, size * sizeof (*yyssp),
- &yyvs1, size * sizeof (*yyvsp),
- &yystacksize);
-#endif
-
- yyss = yyss1; yyvs = yyvs1;
-#ifdef YYLSP_NEEDED
- yyls = yyls1;
-#endif
-#else /* no yyoverflow */
- /* Extend the stack our own way. */
- if (yystacksize >= YYMAXDEPTH)
- {
- yyerror("parser stack overflow");
- return 2;
- }
- yystacksize *= 2;
- if (yystacksize > YYMAXDEPTH)
- yystacksize = YYMAXDEPTH;
- yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
- __yy_memcpy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
- yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
- __yy_memcpy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
-#ifdef YYLSP_NEEDED
- yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
- __yy_memcpy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
-#endif
-#endif /* no yyoverflow */
-
- yyssp = yyss + size - 1;
- yyvsp = yyvs + size - 1;
-#ifdef YYLSP_NEEDED
- yylsp = yyls + size - 1;
-#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Stack size increased to %d\n", yystacksize);
-#endif
-
- if (yyssp >= yyss + yystacksize - 1)
- YYABORT;
- }
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Entering state %d\n", yystate);
-#endif
-
- goto yybackup;
- yybackup:
-
-/* Do appropriate processing given the current state. */
-/* Read a lookahead token if we need one and don't already have one. */
-/* yyresume: */
-
- /* First try to decide what to do without reference to lookahead token. */
-
- yyn = yypact[yystate];
- if (yyn == YYFLAG)
- goto yydefault;
-
- /* Not known => get a lookahead token if don't already have one. */
-
- /* yychar is either YYEMPTY or YYEOF
- or a valid token in external form. */
-
- if (yychar == YYEMPTY)
- {
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Reading a token: ");
-#endif
- yychar = YYLEX;
- }
-
- /* Convert token to internal form (in yychar1) for indexing tables with */
-
- if (yychar <= 0) /* This means end of input. */
- {
- yychar1 = 0;
- yychar = YYEOF; /* Don't call YYLEX any more */
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Now at end of input.\n");
-#endif
- }
- else
- {
- yychar1 = YYTRANSLATE(yychar);
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
- /* Give the individual parser a way to print the precise meaning
- of a token, for further debugging info. */
-#ifdef YYPRINT
- YYPRINT (stderr, yychar, yylval);
-#endif
- fprintf (stderr, ")\n");
- }
-#endif
- }
-
- yyn += yychar1;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
- goto yydefault;
-
- yyn = yytable[yyn];
-
- /* yyn is what to do for this token type in this state.
- Negative => reduce, -yyn is rule number.
- Positive => shift, yyn is new state.
- New state is final state => don't bother to shift,
- just return success.
- 0, or most negative number => error. */
-
- if (yyn < 0)
- {
- if (yyn == YYFLAG)
- goto yyerrlab;
- yyn = -yyn;
- goto yyreduce;
- }
- else if (yyn == 0)
- goto yyerrlab;
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
- /* Shift the lookahead token. */
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
-#endif
-
- /* Discard the token being shifted unless it is eof. */
- if (yychar != YYEOF)
- yychar = YYEMPTY;
-
- *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
-
- /* count tokens shifted since error; after three, turn off error status. */
- if (yyerrstatus) yyerrstatus--;
-
- yystate = yyn;
- goto yynewstate;
-
-/* Do the default action for the current state. */
-yydefault:
-
- yyn = yydefact[yystate];
- if (yyn == 0)
- goto yyerrlab;
-
-/* Do a reduction. yyn is the number of a rule to reduce with. */
-yyreduce:
- yylen = yyr2[yyn];
- if (yylen > 0)
- yyval = yyvsp[1-yylen]; /* implement default value of the action */
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- int i;
-
- fprintf (stderr, "Reducing via rule %d (line %d), ",
- yyn, yyrline[yyn]);
-
- /* Print the symbols being reduced, and their result. */
- for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
- fprintf (stderr, "%s ", yytname[yyrhs[i]]);
- fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
- }
-#endif
-
-
- switch (yyn) {
-
-case 3:
-#line 193 "./getdate.y"
-{
- yyHaveTime++;
- ;
- break;}
-case 4:
-#line 196 "./getdate.y"
-{
- yyHaveZone++;
- ;
- break;}
-case 5:
-#line 199 "./getdate.y"
-{
- yyHaveDate++;
- ;
- break;}
-case 6:
-#line 202 "./getdate.y"
-{
- yyHaveDay++;
- ;
- break;}
-case 7:
-#line 205 "./getdate.y"
-{
- yyHaveRel++;
- ;
- break;}
-case 9:
-#line 211 "./getdate.y"
-{
- yyHour = yyvsp[-1].Number;
- yyMinutes = 0;
- yySeconds = 0;
- yyMeridian = yyvsp[0].Meridian;
- ;
- break;}
-case 10:
-#line 217 "./getdate.y"
-{
- yyHour = yyvsp[-3].Number;
- yyMinutes = yyvsp[-1].Number;
- yySeconds = 0;
- yyMeridian = yyvsp[0].Meridian;
- ;
- break;}
-case 11:
-#line 223 "./getdate.y"
-{
- yyHour = yyvsp[-3].Number;
- yyMinutes = yyvsp[-1].Number;
- yyMeridian = MER24;
- yyDSTmode = DSToff;
- yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
- ;
- break;}
-case 12:
-#line 230 "./getdate.y"
-{
- yyHour = yyvsp[-5].Number;
- yyMinutes = yyvsp[-3].Number;
- yySeconds = yyvsp[-1].Number;
- yyMeridian = yyvsp[0].Meridian;
- ;
- break;}
-case 13:
-#line 236 "./getdate.y"
-{
- yyHour = yyvsp[-5].Number;
- yyMinutes = yyvsp[-3].Number;
- yySeconds = yyvsp[-1].Number;
- yyMeridian = MER24;
- yyDSTmode = DSToff;
- yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
- ;
- break;}
-case 14:
-#line 246 "./getdate.y"
-{
- yyTimezone = yyvsp[0].Number;
- yyDSTmode = DSToff;
- ;
- break;}
-case 15:
-#line 250 "./getdate.y"
-{
- yyTimezone = yyvsp[0].Number;
- yyDSTmode = DSTon;
- ;
- break;}
-case 16:
-#line 255 "./getdate.y"
-{
- yyTimezone = yyvsp[-1].Number;
- yyDSTmode = DSTon;
- ;
- break;}
-case 17:
-#line 261 "./getdate.y"
-{
- yyDayOrdinal = 1;
- yyDayNumber = yyvsp[0].Number;
- ;
- break;}
-case 18:
-#line 265 "./getdate.y"
-{
- yyDayOrdinal = 1;
- yyDayNumber = yyvsp[-1].Number;
- ;
- break;}
-case 19:
-#line 269 "./getdate.y"
-{
- yyDayOrdinal = yyvsp[-1].Number;
- yyDayNumber = yyvsp[0].Number;
- ;
- break;}
-case 20:
-#line 275 "./getdate.y"
-{
- yyMonth = yyvsp[-2].Number;
- yyDay = yyvsp[0].Number;
- ;
- break;}
-case 21:
-#line 279 "./getdate.y"
-{
- yyMonth = yyvsp[-4].Number;
- yyDay = yyvsp[-2].Number;
- yyYear = yyvsp[0].Number;
- ;
- break;}
-case 22:
-#line 284 "./getdate.y"
-{
- /* ISO 8601 format. yyyy-mm-dd. */
- yyYear = yyvsp[-2].Number;
- yyMonth = -yyvsp[-1].Number;
- yyDay = -yyvsp[0].Number;
- ;
- break;}
-case 23:
-#line 290 "./getdate.y"
-{
- /* e.g. 17-JUN-1992. */
- yyDay = yyvsp[-2].Number;
- yyMonth = yyvsp[-1].Number;
- yyYear = -yyvsp[0].Number;
- ;
- break;}
-case 24:
-#line 296 "./getdate.y"
-{
- yyMonth = yyvsp[-1].Number;
- yyDay = yyvsp[0].Number;
- ;
- break;}
-case 25:
-#line 300 "./getdate.y"
-{
- yyMonth = yyvsp[-3].Number;
- yyDay = yyvsp[-2].Number;
- yyYear = yyvsp[0].Number;
- ;
- break;}
-case 26:
-#line 305 "./getdate.y"
-{
- yyMonth = yyvsp[0].Number;
- yyDay = yyvsp[-1].Number;
- ;
- break;}
-case 27:
-#line 309 "./getdate.y"
-{
- yyMonth = yyvsp[-1].Number;
- yyDay = yyvsp[-2].Number;
- yyYear = yyvsp[0].Number;
- ;
- break;}
-case 28:
-#line 316 "./getdate.y"
-{
- yyRelSeconds = -yyRelSeconds;
- yyRelMonth = -yyRelMonth;
- ;
- break;}
-case 30:
-#line 323 "./getdate.y"
-{
- yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
- ;
- break;}
-case 31:
-#line 326 "./getdate.y"
-{
- yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
- ;
- break;}
-case 32:
-#line 329 "./getdate.y"
-{
- yyRelSeconds += yyvsp[0].Number * 60L;
- ;
- break;}
-case 33:
-#line 332 "./getdate.y"
-{
- yyRelSeconds += yyvsp[-1].Number;
- ;
- break;}
-case 34:
-#line 335 "./getdate.y"
-{
- yyRelSeconds += yyvsp[-1].Number;
- ;
- break;}
-case 35:
-#line 338 "./getdate.y"
-{
- yyRelSeconds++;
- ;
- break;}
-case 36:
-#line 341 "./getdate.y"
-{
- yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
- ;
- break;}
-case 37:
-#line 344 "./getdate.y"
-{
- yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
- ;
- break;}
-case 38:
-#line 347 "./getdate.y"
-{
- yyRelMonth += yyvsp[0].Number;
- ;
- break;}
-case 39:
-#line 352 "./getdate.y"
-{
- if (yyHaveTime && yyHaveDate && !yyHaveRel)
- yyYear = yyvsp[0].Number;
- else {
- if(yyvsp[0].Number>10000) {
- yyHaveDate++;
- yyDay= (yyvsp[0].Number)%100;
- yyMonth= (yyvsp[0].Number/100)%100;
- yyYear = yyvsp[0].Number/10000;
- }
- else {
- yyHaveTime++;
- if (yyvsp[0].Number < 100) {
- yyHour = yyvsp[0].Number;
- yyMinutes = 0;
- }
- else {
- yyHour = yyvsp[0].Number / 100;
- yyMinutes = yyvsp[0].Number % 100;
- }
- yySeconds = 0;
- yyMeridian = MER24;
- }
- }
- ;
- break;}
-case 40:
-#line 379 "./getdate.y"
-{
- yyval.Meridian = MER24;
- ;
- break;}
-case 41:
-#line 382 "./getdate.y"
-{
- yyval.Meridian = yyvsp[0].Meridian;
- ;
- break;}
-}
- /* the action file gets copied in in place of this dollarsign */
-#line 487 "/usr/share/bison.simple"
-
- yyvsp -= yylen;
- yyssp -= yylen;
-#ifdef YYLSP_NEEDED
- yylsp -= yylen;
+#define YYSTACKSIZE 500
+#define YYMAXDEPTH 500
#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- short *ssp1 = yyss - 1;
- fprintf (stderr, "state stack now");
- while (ssp1 != yyssp)
- fprintf (stderr, " %d", *++ssp1);
- fprintf (stderr, "\n");
- }
#endif
-
- *++yyvsp = yyval;
-
-#ifdef YYLSP_NEEDED
- yylsp++;
- if (yylen == 0)
- {
- yylsp->first_line = yylloc.first_line;
- yylsp->first_column = yylloc.first_column;
- yylsp->last_line = (yylsp-1)->last_line;
- yylsp->last_column = (yylsp-1)->last_column;
- yylsp->text = 0;
- }
- else
- {
- yylsp->last_line = (yylsp+yylen-1)->last_line;
- yylsp->last_column = (yylsp+yylen-1)->last_column;
- }
-#endif
-
- /* Now "shift" the result of the reduction.
- Determine what state that goes to,
- based on the state we popped back to
- and the rule number reduced by. */
-
- yyn = yyr1[yyn];
-
- yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
- if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
- yystate = yytable[yystate];
- else
- yystate = yydefgoto[yyn - YYNTBASE];
-
- goto yynewstate;
-
-yyerrlab: /* here on detecting error */
-
- if (! yyerrstatus)
- /* If not already recovering from an error, report this error. */
- {
- ++yynerrs;
-
-#ifdef YYERROR_VERBOSE
- yyn = yypact[yystate];
-
- if (yyn > YYFLAG && yyn < YYLAST)
- {
- int size = 0;
- char *msg;
- int x, count;
-
- count = 0;
- /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
- for (x = (yyn < 0 ? -yyn : 0);
- x < (sizeof(yytname) / sizeof(char *)); x++)
- if (yycheck[x + yyn] == x)
- size += strlen(yytname[x]) + 15, count++;
- msg = (char *) malloc(size + 15);
- if (msg != 0)
- {
- strcpy(msg, "parse error");
-
- if (count < 5)
- {
- count = 0;
- for (x = (yyn < 0 ? -yyn : 0);
- x < (sizeof(yytname) / sizeof(char *)); x++)
- if (yycheck[x + yyn] == x)
- {
- strcat(msg, count == 0 ? ", expecting `" : " or `");
- strcat(msg, yytname[x]);
- strcat(msg, "'");
- count++;
- }
- }
- yyerror(msg);
- free(msg);
- }
- else
- yyerror ("parse error; also virtual memory exceeded");
- }
- else
-#endif /* YYERROR_VERBOSE */
- yyerror("parse error");
- }
-
- goto yyerrlab1;
-yyerrlab1: /* here on error raised explicitly by an action */
-
- if (yyerrstatus == 3)
- {
- /* if just tried and failed to reuse lookahead token after an error, discard it. */
-
- /* return failure if at end of input */
- if (yychar == YYEOF)
- YYABORT;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
-#endif
-
- yychar = YYEMPTY;
- }
-
- /* Else will try to reuse lookahead token
- after shifting the error token. */
-
- yyerrstatus = 3; /* Each real token shifted decrements this */
-
- goto yyerrhandle;
-
-yyerrdefault: /* current state does not do anything special for the error token. */
-
-#if 0
- /* This is wrong; only states that explicitly want error tokens
- should shift them. */
- yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
- if (yyn) goto yydefault;
-#endif
-
-yyerrpop: /* pop the current state because it cannot handle the error token */
-
- if (yyssp == yyss) YYABORT;
- yyvsp--;
- yystate = *--yyssp;
-#ifdef YYLSP_NEEDED
- yylsp--;
-#endif
-
-#if YYDEBUG != 0
- if (yydebug)
- {
- short *ssp1 = yyss - 1;
- fprintf (stderr, "Error: state stack now");
- while (ssp1 != yyssp)
- fprintf (stderr, " %d", *++ssp1);
- fprintf (stderr, "\n");
- }
-#endif
-
-yyerrhandle:
-
- yyn = yypact[yystate];
- if (yyn == YYFLAG)
- goto yyerrdefault;
-
- yyn += YYTERROR;
- if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
- goto yyerrdefault;
-
- yyn = yytable[yyn];
- if (yyn < 0)
- {
- if (yyn == YYFLAG)
- goto yyerrpop;
- yyn = -yyn;
- goto yyreduce;
- }
- else if (yyn == 0)
- goto yyerrpop;
-
- if (yyn == YYFINAL)
- YYACCEPT;
-
-#if YYDEBUG != 0
- if (yydebug)
- fprintf(stderr, "Shifting error token, ");
-#endif
-
- *++yyvsp = yylval;
-#ifdef YYLSP_NEEDED
- *++yylsp = yylloc;
-#endif
-
- yystate = yyn;
- goto yynewstate;
-}
-#line 387 "./getdate.y"
-
+int yydebug;
+int yynerrs;
+int yyerrflag;
+int yychar;
+short *yyssp;
+YYSTYPE *yyvsp;
+YYSTYPE yyval;
+YYSTYPE yylval;
+short yyss[YYSTACKSIZE];
+YYSTYPE yyvs[YYSTACKSIZE];
+#define yystacksize YYSTACKSIZE
+#line 393 "../../lib/getdate.y"
/* Month and day table. */
static TABLE const MonthDayTable[] = {
@@ -1942,3 +1018,485 @@ main(ac, av)
/* NOTREACHED */
}
#endif /* defined(TEST) */
+#line 1022 "y.tab.c"
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+int
+yyparse()
+{
+ register int yym, yyn, yystate;
+#if YYDEBUG
+ register char *yys;
+ extern char *getenv();
+
+ if (yys = getenv("YYDEBUG"))
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = (-1);
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+ *yyssp = yystate = 0;
+
+yyloop:
+ if (yyn = yydefred[yystate]) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ yychar = (-1);
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+#ifdef lint
+ goto yynewerror;
+#endif
+yynewerror:
+ yyerror("syntax error");
+#ifdef lint
+ goto yyerrlab;
+#endif
+yyerrlab:
+ ++yynerrs;
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate = yytable[yyn];
+ *++yyvsp = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yyssp);
+#endif
+ if (yyssp <= yyss) goto yyabort;
+ --yyssp;
+ --yyvsp;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == 0) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = (-1);
+ goto yyloop;
+ }
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ yyval = yyvsp[1-yym];
+ switch (yyn)
+ {
+case 3:
+#line 198 "../../lib/getdate.y"
+{
+ yyHaveTime++;
+ }
+break;
+case 4:
+#line 201 "../../lib/getdate.y"
+{
+ yyHaveZone++;
+ }
+break;
+case 5:
+#line 204 "../../lib/getdate.y"
+{
+ yyHaveDate++;
+ }
+break;
+case 6:
+#line 207 "../../lib/getdate.y"
+{
+ yyHaveDay++;
+ }
+break;
+case 7:
+#line 210 "../../lib/getdate.y"
+{
+ yyHaveRel++;
+ }
+break;
+case 9:
+#line 216 "../../lib/getdate.y"
+{
+ yyHour = yyvsp[-1].Number;
+ yyMinutes = 0;
+ yySeconds = 0;
+ yyMeridian = yyvsp[0].Meridian;
+ }
+break;
+case 10:
+#line 222 "../../lib/getdate.y"
+{
+ yyHour = yyvsp[-3].Number;
+ yyMinutes = yyvsp[-1].Number;
+ yySeconds = 0;
+ yyMeridian = yyvsp[0].Meridian;
+ }
+break;
+case 11:
+#line 228 "../../lib/getdate.y"
+{
+ yyHour = yyvsp[-3].Number;
+ yyMinutes = yyvsp[-1].Number;
+ yyMeridian = MER24;
+ yyDSTmode = DSToff;
+ yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
+ }
+break;
+case 12:
+#line 235 "../../lib/getdate.y"
+{
+ yyHour = yyvsp[-5].Number;
+ yyMinutes = yyvsp[-3].Number;
+ yySeconds = yyvsp[-1].Number;
+ yyMeridian = yyvsp[0].Meridian;
+ }
+break;
+case 13:
+#line 241 "../../lib/getdate.y"
+{
+ yyHour = yyvsp[-5].Number;
+ yyMinutes = yyvsp[-3].Number;
+ yySeconds = yyvsp[-1].Number;
+ yyMeridian = MER24;
+ yyDSTmode = DSToff;
+ yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
+ }
+break;
+case 14:
+#line 251 "../../lib/getdate.y"
+{
+ yyTimezone = yyvsp[0].Number;
+ yyDSTmode = DSToff;
+ }
+break;
+case 15:
+#line 255 "../../lib/getdate.y"
+{
+ yyTimezone = yyvsp[0].Number;
+ yyDSTmode = DSTon;
+ }
+break;
+case 16:
+#line 260 "../../lib/getdate.y"
+{
+ yyTimezone = yyvsp[-1].Number;
+ yyDSTmode = DSTon;
+ }
+break;
+case 17:
+#line 266 "../../lib/getdate.y"
+{
+ yyDayOrdinal = 1;
+ yyDayNumber = yyvsp[0].Number;
+ }
+break;
+case 18:
+#line 270 "../../lib/getdate.y"
+{
+ yyDayOrdinal = 1;
+ yyDayNumber = yyvsp[-1].Number;
+ }
+break;
+case 19:
+#line 274 "../../lib/getdate.y"
+{
+ yyDayOrdinal = yyvsp[-1].Number;
+ yyDayNumber = yyvsp[0].Number;
+ }
+break;
+case 20:
+#line 280 "../../lib/getdate.y"
+{
+ yyMonth = yyvsp[-2].Number;
+ yyDay = yyvsp[0].Number;
+ }
+break;
+case 21:
+#line 284 "../../lib/getdate.y"
+{
+ yyMonth = yyvsp[-4].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ }
+break;
+case 22:
+#line 289 "../../lib/getdate.y"
+{
+ /* ISO 8601 format. yyyy-mm-dd. */
+ yyYear = yyvsp[-2].Number;
+ yyMonth = -yyvsp[-1].Number;
+ yyDay = -yyvsp[0].Number;
+ }
+break;
+case 23:
+#line 295 "../../lib/getdate.y"
+{
+ /* e.g. 17-JUN-1992. */
+ yyDay = yyvsp[-2].Number;
+ yyMonth = yyvsp[-1].Number;
+ yyYear = -yyvsp[0].Number;
+ }
+break;
+case 24:
+#line 301 "../../lib/getdate.y"
+{
+ yyMonth = yyvsp[-1].Number;
+ yyDay = yyvsp[0].Number;
+ }
+break;
+case 25:
+#line 305 "../../lib/getdate.y"
+{
+ yyMonth = yyvsp[-3].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ }
+break;
+case 26:
+#line 310 "../../lib/getdate.y"
+{
+ yyMonth = yyvsp[0].Number;
+ yyDay = yyvsp[-1].Number;
+ }
+break;
+case 27:
+#line 314 "../../lib/getdate.y"
+{
+ yyMonth = yyvsp[-1].Number;
+ yyDay = yyvsp[-2].Number;
+ yyYear = yyvsp[0].Number;
+ }
+break;
+case 28:
+#line 321 "../../lib/getdate.y"
+{
+ yyRelSeconds = -yyRelSeconds;
+ yyRelMonth = -yyRelMonth;
+ }
+break;
+case 30:
+#line 328 "../../lib/getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
+ }
+break;
+case 31:
+#line 331 "../../lib/getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
+ }
+break;
+case 32:
+#line 334 "../../lib/getdate.y"
+{
+ yyRelSeconds += yyvsp[0].Number * 60L;
+ }
+break;
+case 33:
+#line 337 "../../lib/getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number;
+ }
+break;
+case 34:
+#line 340 "../../lib/getdate.y"
+{
+ yyRelSeconds += yyvsp[-1].Number;
+ }
+break;
+case 35:
+#line 343 "../../lib/getdate.y"
+{
+ yyRelSeconds++;
+ }
+break;
+case 36:
+#line 346 "../../lib/getdate.y"
+{
+ yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
+ }
+break;
+case 37:
+#line 349 "../../lib/getdate.y"
+{
+ yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
+ }
+break;
+case 38:
+#line 352 "../../lib/getdate.y"
+{
+ yyRelMonth += yyvsp[0].Number;
+ }
+break;
+case 39:
+#line 357 "../../lib/getdate.y"
+{
+ if (yyHaveTime && yyHaveDate && !yyHaveRel)
+ yyYear = yyvsp[0].Number;
+ else {
+ if(yyvsp[0].Number>10000) {
+ yyHaveDate++;
+ yyDay= (yyvsp[0].Number)%100;
+ yyMonth= (yyvsp[0].Number/100)%100;
+ yyYear = yyvsp[0].Number/10000;
+ }
+ else {
+ yyHaveTime++;
+ if (yyvsp[0].Number < 100) {
+ yyHour = yyvsp[0].Number;
+ yyMinutes = 0;
+ }
+ else {
+ yyHour = yyvsp[0].Number / 100;
+ yyMinutes = yyvsp[0].Number % 100;
+ }
+ yySeconds = 0;
+ yyMeridian = MER24;
+ }
+ }
+ }
+break;
+case 40:
+#line 384 "../../lib/getdate.y"
+{
+ yyval.Meridian = MER24;
+ }
+break;
+case 41:
+#line 387 "../../lib/getdate.y"
+{
+ yyval.Meridian = yyvsp[0].Meridian;
+ }
+break;
+#line 1447 "y.tab.c"
+ }
+ yyssp -= yym;
+ yystate = *yyssp;
+ yyvsp -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yyssp = YYFINAL;
+ *++yyvsp = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = yylex()) < 0) yychar = 0;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = 0;
+ if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
+ if (!yys) yys = "illegal-symbol";
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == 0) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yyssp, yystate);
+#endif
+ if (yyssp >= yyss + yystacksize - 1)
+ {
+ goto yyoverflow;
+ }
+ *++yyssp = yystate;
+ *++yyvsp = yyval;
+ goto yyloop;
+yyoverflow:
+ yyerror("yacc stack overflow");
+yyabort:
+ return (1);
+yyaccept:
+ return (0);
+}
diff --git a/gnu/usr.bin/cvs/lib/getdate.y b/gnu/usr.bin/cvs/lib/getdate.y
index 57871426745..046fa3fb1ee 100644
--- a/gnu/usr.bin/cvs/lib/getdate.y
+++ b/gnu/usr.bin/cvs/lib/getdate.y
@@ -96,9 +96,18 @@ struct timeb {
#include <stdlib.h>
#endif
-#if defined (HAVE_ALLOCA_H)
-#include <alloca.h>
-#endif
+/* NOTES on rebuilding getdate.c (particularly for inclusion in CVS
+ releases):
+
+ We don't want to mess with all the portability hassles of alloca.
+ In particular, most (all?) versions of bison will use alloca in
+ their parser. If bison works on your system (e.g. it should work
+ with gcc), then go ahead and use it, but the more general solution
+ is to use byacc instead of bison, which should generate a portable
+ parser. I played with adding "#define alloca dont_use_alloca", to
+ give an error if the parser generator uses alloca (and thus detect
+ unportable getdate.c's), but that seems to cause as many problems
+ as it solves. */
extern struct tm *gmtime();
extern struct tm *localtime();
@@ -107,10 +116,6 @@ extern struct tm *localtime();
#define yylex getdate_yylex
#define yyerror getdate_yyerror
-#if !defined(lint) && !defined(SABER)
-static char RCS[] = "$CVSid: @(#)getdate.y 1.11 94/09/21 $";
-#endif /* !defined(lint) && !defined(SABER) */
-
static int yylex ();
static int yyerror ();
diff --git a/gnu/usr.bin/cvs/lib/memmove.c b/gnu/usr.bin/cvs/lib/memmove.c
deleted file mode 100644
index 8818d46544c..00000000000
--- a/gnu/usr.bin/cvs/lib/memmove.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* memmove -- copy memory regions of arbitary length
- Copyright (C) 1991 Free Software Foundation, Inc.
-
-This file is part of the libiberty library.
-Libiberty is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public
-License as published by the Free Software Foundation; either
-version 2 of the License, or (at your option) any later version.
-
-Libiberty is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with libiberty; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-
-/*
-
-NAME
-
- memmove -- copy memory regions of arbitary length
-
-SYNOPSIS
-
- void memmove (void *out, const void *in, size_t n);
-
-DESCRIPTION
-
- Copy LENGTH bytes from memory region pointed to by IN to memory
- region pointed to by OUT.
-
- Regions can be overlapping.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef __STDC__
-#include <stddef.h>
-#else
-#define size_t unsigned long
-#endif
-
-void *
-memmove (out, in, length)
- void *out;
- const void* in;
- size_t length;
-{
- bcopy(in, out, length);
- return out;
-}
diff --git a/gnu/usr.bin/cvs/macintosh/maccvs.projects.sit.hqx b/gnu/usr.bin/cvs/macintosh/maccvs.projects.sit.hqx
deleted file mode 100644
index 5321000db86..00000000000
--- a/gnu/usr.bin/cvs/macintosh/maccvs.projects.sit.hqx
+++ /dev/null
@@ -1,270 +0,0 @@
-(This file must be converted with BinHex 4.0)
-:$d0A)&"bEfTPBh4c,R0TG!"6594%8dP8)3#3"$+q!*!%c(*6593K!!%!!$+qFNa
-KG3,r!*!$&[rr)#!,3eFJ8(*[DQ9MG(-!N"35l`#3!c%!$J&V!0B!N!-#!*!2KJ!
-!!3$rN!3"!+cdQ2ZY'C(1!*!&!D1m!*!'-MJ!N!VU-Jd0#NeKBd0@8bif1'X!N"8
-(i`#3%4B!!"SB!*!$&J!(!%f3!e"53eG*43%!Ukq,G+dCNLi!!#S9!!#S$J!!#)8
-!!"#GjiZP&3#3"Y)#$F"&C5Yci+Dj+DIAE5CKQr+9dddVc9mh)q`fB8P@IT'0ClG
-ZHYQ[am36DTaD4ikIYqD!hFTDmmPUY9PHrRUecq`B18iSf@66ifGZFT[G*VIC2X+
-2NLdPR2!Nciq5Ci344RK(RT&R8I+E--)lb@EENc$#)XF**icX*j56b9DJm0PeqG8
-40NPEphTN$fLEEA,F)rc)l5H$6BlMb3BQH1",-a02*)MSLeZ*lXCAqJ'+41&Jm"b
-#1MNrGS`LR1rE4p&JX06Pp6RDh,DPbajTNp$+j9*D(*j9$8!aR9cFr%m[aZ1jjrF
-QL(j56R4[G6#iEar`EHFFq(C`(Jc5Bj`[@8)l18I,A8%%jV'EFr4,FSkA+Fl4VjX
-cp0ZM9BQq`9AdqbERk2FijqMh,Fl4i3R1dHrE@VG5-Sf14k*Tb1iPXejRHZ6$-Y'
-P#[9&4ChLS1NjIQQjMfKQ%plG3bC"Q)XHjmi*$Ll9TP-1EH*%Up'ja1b+4Vbqk#6
-f)U!U&8HNC$DI#!C@k5G6"CMEl,BZAEE'kJa&(JR%,c6+G&!8aq81XjE(BZ'rmZ&
-kE-4hZD)iM3&`q+1q,Q-!(#l&fCM[8qi-G9KAGFDLm346j')2PmZj`L!!KmIa0@1
-!ZEDi@bi"[)8MVXCpaJ!ie-hKMJ)rP)E'2$r84*G"!)l@K[C@bCBEVFAPX6Uqj*J
-rrbU+0!k6c6Gr[L%!ML+ElrT!rS8MCKJ`epJNN!!E1#6Ej[raV#+,irTBk62!SAK
-9RcImi8$5Fiej9D-!(,l*bHERbS+0FCJCal80FJ1(C2Y!Yif&'6KD!YZ[pfKh0"I
-d8!8h+@aBb%SE9&SHc,93''YHZaUC+00ELK)8ZGMMYX+pLX-`3*NfVeKY,Fc$TAM
-bmc$q8,LiSehXF9[KAX(aNF+p`V,E#MH(ikE#,H#B8VL&Z8iTh"b1Q`Vh%Sj2&1l
-9JGa5Z(NF8`Vh%Sb2&@i1Kc'!`Z8`#&#QRP"Nb@,VYQ9,,b[6NSmf-)$N0YA8"Xl
-KZ,Nj#r1BfTaj($Ffc#8F(fqB()iL@di0&J-(L&q3!*iQ@cJd+H21+qi2'F)iSKe
-E*R%dGfc*ibKaA6RVCiIUFV",`3!JrVEaLM%0MBPr`B%0%jl8-*pP(''[UPSGdFj
-B+(aKZKP'BpF(f1cak9`re3`M'LqR&@rJb'r12-p'0PjLNQC68E+!(5l`dd`6m-4
-)G[[J8m9LX+q#+PHr3qXIHSISQ"DdrY'6I6fdq[iK5Uk-0kc8fmm@Jdr9X2&)Lar
-63CKA""AMa@LN(lp5l'p$Ye1LYjj-dmqpk[mbdId$H+MjD,jh@'+#F!MJ2dj9Vle
-)kcIF``rHCpX5m10G$q`qCj'R*8cYdF-MN`639reYY0iMDbMl+NpShpkhV@,`J%N
--2XeA1G-%pM4Jp0%Vi-"dZpd1$@$r$`GLBXdr1&"X!-#"INbDD[F-+0P*AZ$!c(V
-YfrYQE*`$BpKe$XbX(qF!cQ[rjF!rpi!4!!H)lX)Hf"@M+Q@"d3!(bX!"Zm1cmN(
-h+[XR('JAGaNRF%!cN!"Cr6eA1G#l-CEq[RDm`!(dd5X9*-fbTmrilUiB+e9l8m$
-V$m491qh@*PP4h8qdBjfF+MiYTfUIKDX1`@piMZE(derZ90d[UKqSS@9cIddd`,1
-G3lrEhL5UAcK-*RP[Z)lS`"I`LVpk92I,HlFm3E5QMYjpEdK1lMmT*hpiLZZLik(
-Ab9*j31YTUBc)b5LFIqZ1bmR)#8V*+6NT*ppL([1eQYQ5iC)N*pq%Mj(M)""ch$Q
-#0[R'LBC4A96G$fhYB!l-RZ!!$J"aEc`881e'+KbSQH!!UTP9B1$#!5Akp8"F#AX
-M#F-8$M549(pC$baIkejPc46IPj1rHTH4kbK+Kj!$diTLhKmj25UR(YiPjKhUiET
-`RYSSR&e0F[+C8RL-5GjMHSRS-(VK,U&p$r@3!-RCMClkGra9ad[m"Dp+bAbb(Kf
-H"TT'cM'&d8R)UB&D1I8m@*2'4R4(cI$`(6A8661)0#G'Yh"ZI8E-qm-L)"M#c)E
-I@T5Ga-+h$eNVj"5)8icHCHj3Cb`FX+i)"(*hIm15B&dVM&p)J+M5EQImd9hKZL@
-m(0Fd[1'2rZB)Hp4e*rie6dSZ[ST)Zpf+cV4ri"Vr0jjXm8(4)b4T"dqVprY%Mql
-N4d9RaKSZcRVXcCeHRfqVkX-&9ldmcD`p[P46(TPA3qHV4N'aBB1Dm-Ce1@I8%&A
-iUi'flRMVMEil5Y11'),-9e51rA(#1#CHCPCBq%,D#"p(Dd"0f(kQ1'biN!#0@QM
-1UaCG8FJiMijHlSd,5$ZUErkXES6Tlhm+-8+*qLNHQ%P#)qajkN&Q"-!G#5K`mc%
--#2ll#NhcfU*GNd)"QiI0,ZP%chNhP%Jl*QE$-IDIQI'rlSMlkKC8iA*1Fm4fNQ*
-a@*8q4c@a0RBcL8ChD`[ZGk,&0*!![EM4fQlk20)UVUdj3`Z4DMlaRH[S+dKEZ,C
-e$V'AA611H9iQ0p)qVRApPYU4iRU&im,$Y!(A+qj$Qhj$m0$2HBaVR@m3r%#eZ"-
-54AE6EY4`&b3+,U6[S2B#epcl'FqGflKQ5p'282XTeaE2SKG4'p4`2dQ[`&AaADi
-e2dNr4qeCVPRISb'L1XfYTIb5AXH*8X0DYjp1BiPSA[AD"qMh4(2ADV@B!)[QJLf
-BhfQ"[`I0e@i@,AeL0PLNmB"q`4I4ZmrESG!(5qDXpNj6%618H(4,`*H`JPYU+"U
-aC1UZN!$UQk'lB60@XNcGiie(3T&0DRQQ@F1f40bVQK[mS83dEQU-4K,Q9Qpm8b"
-K@Hlc"@"'8lb*cAL[Y5RMhaBiS[l!bN#NG13A"YSc(9"jfT5B`DfA-l$0MNBAQTA
-aMhNb1%CqdM1G5h##Dmpe2"EBAdI3D%l&E,Q-[DSC'#1q9HfCh[lr!!i!Yc*YeYR
-e$MU[Th9H4l2dbXc-kc`lZIETG5[A,h[6m056'Tj6hrKU9ekpChQC6Ic1RKb,h#D
-hcmK[ApY("Ta`-YKN5ik6hbFCm#2mb2',E(+EE-QafmG+mY`VYXeB*Q'%8q!'bGE
-Vm,'2RTGA+Xm"l6Gj6QDEc2J"N!!06!m2[!*eATCZAIFKK$$mRi$3Vek%rkp$cJA
-rXq$r-H4%dj%$P6MpLPXh%+VSH#%IiCTak"m&5a$U@MFLTq3`q[60)'$4F$J!$k'
-5B8E)A3crihLM`m-rk-AcDBh&m$q1jkLDGq`-hS34LqYVPaCADidK*D5TKQU82r6
-RLZHU0Rl!`m5$S289eY`C4I1SRZ,'pQ*5`fNm+"+9S"0G4fJ1RhL9rHLbCR3MbR+
--[f9F0pDrk&F&1K`kmJ8DLEDLVN03`#&#(Kl34rSIS9cJ@5lldF6#lLU+#AjqMH+
-ZA&9E0QYf5rH2)B,Npd9G0&!4r8R4Zr!02AU(I(I"phlbIB4rGePjrRZ#YlqSm#d
-)q'Eel%FII%,Lh@l13,hi"XH[mI[$pU!C+-raqE$2&bLK!"%+)-A258kJ$81iBKK
-*M&Q`(&KC-P-VRqfC8P`*R9a@"U`63*hDcXPiFifVZSTNJ'G1mUY#`N1#3r$LR5H
-S"hrh%8H&$"V'DXd$YUbS,3201!0*DchHB0Ck[!&Pm3kjUQ[$)5hJVBS%h%DCeaG
-4ZdYiqB@D,B"D8lf3!'5J2`j+A,FHD0+mCFepTD*pZ5[$Z+0ZdHSkNN(C$$92$iB
-e2@!NB6X2[IBq3b8CP-03Xd0Z[kI-RDJ8DR@qYChA#KR3%iTDB+LK9MA8S$Ae331
-@4k"k8"j9Gq482!1PSReM2rXE4i8-bQHS1BV(V`95Z"CU!820FcHVlTB8VS9Db&$
-c+DSH#5GJ,G6K*UT2-3bYUIele"%-0GIYdp4!XY*6U%8QUZlhDqG44c,83RG)9F*
-U!e#T&pP#(F@Cjfk&QHSmmbjLU0NHV5NK#eqKAXcj#P3J`p)3AbrK(9*$)6ed[N1
-M'HT`Y5fS"$`035AFr"@fK6U'Xla*mkP'T$&ClVkaarDBU-IfS,'FH8dD9"T3r)R
-@@V@1iaaU9ScHe[5KAXSje+`CB6f8P+%ikQ9F864[3!qTja4P[)RU$qUKXcTd8+!
-HK'QIpG@RZeX'qaT$[Cc2$6lGQjNEBUKAF'd!e-cF%%1pN[F982e'UP`,YCMheDm
--P"T(RFMjkYFp%G#80&pMU&Ia$[RE!jl'2KdrJhSeVc@J0``)Xi8kLD%@"*@3!+&
-UJ5Bp-HIeS%lQc!0KGDIPbd+pKLXP4I@TVDU[Gi3&V,m+e,qLDlNfK'#Z[U!0*9(
-8j(KpZYBTR%1!#Y2b1Ek@QULU1`)X'N+GbMN88S0kZV-@kR9FKd+kRY,N8kM6605
-`-L#`&QSCeb(Q!D4FLTkjSGa%$5[K5+Ua9Uh6HBI5FpFCe1Xjb`IE'NHG`6X8#AT
-J9KlSd)F#p80d3`pUQJda4CR*Y3%)C)"TNpD'@+hJ#!V8K[#!$X93Ch(8p5%P'!6
-#ISpk%rKX%2P+b1Y2bcPJ(4#S"p"XKTVA&"J!MD2Hc&'pDRL!HKEUR*1S2Le`$R8
-Z3md&9$$-"PJH3lhPC+f!H[e3VEFbe"a!ACpf[Lc8H3c9kIIFQ&'['1TmAQY)pDT
-YjfZYi#`hP&CeQVZr54EU!SCDB'MHCM"5I!RZ@CUhd%3&SbHBp&j1S9Bbe%++DS$
-4eJGVSGl'@Gif5$d,G4(R8,YU"")6laR8UJVULHBBBBqQTkE+cN96Ad38P@B@Fp6
-f9X@ARN8lelea18FPQ5A-`bi`fSebm,kJ5lh)Hprqr4''5M0,'DSc#&4)6lfGllc
-f@eiVbGc18,1TAjk#lIcCRLFj+XNXLhBSh"i%Gk1[3ep-[**hL'5U'HS)f2YS"Ld
-[9`+'GJEij8rIhF43DDD'S4DCU)PkAjVAqNH'5M2,'I1bkc4rDPiMI*dqhq3VC&B
-`e0cDX)IX$L4a1l@lrmj45FB9CB2EScBPfI$f(hjMmK8bGc"8i[@#6UCU(6AT,la
-@NPNCV9A6hH%q'`AYV94'meT*TMD+fZ31*&%lR42'mPT*TSkKjK08-Y%RHJ5+d#5
-dS3R9-`jGA+N(2"TC9P"mX&B4!TqM'ljcBXFE(*9N9R%fH,33mFZ6E!$QV"%F@S2
-Zj2TDPp)JaYI2rQRb&6+V1FXAY8+T+9LV3hIa@UZ)3jbZY3IeESCDX#!Bp+PeLUm
-P`E`He(XBkSM+ZSAeBFd(01SYf8*G`e$cABUl4I(f0mP#[CHK&VTFPA@`ZE93Eq[
-&Y9$A4V8KR0,B[@qrQ@Ib&6)0$,@3!#S+Z-4U(p1"fqm*PVq(eR'qNZN`N!$DQ1R
-8'Pif@3iCKGFD8--`0S6,`E[YVIAcjda9*TP'KTS$L*l8!)"HfR4G2Cmf5-E0eB[
-d0G*A*iPA[Rceh`b9CM`F04)!5cmeY1epGAX*la$*U&%1TC'"Eq-%mmDK*SBkdTb
-L9""RjA5RA[)IAFRl5M*HbqP*Y)K1b#GRj@DZP'ibUU@9F[94&qFVb@JQbf&938N
--+!4edG44BX)HKHlMYDERC)CDqNX6&6)Yh$N!$S99rcNrchGKFiZcJ@6m[+mq$9C
-kdY2'SY)$SN-(8)$V8#3YVS5[*qC`cD-CRD1QCcbU$9m8(cERFXJ%BrXSU9RCBX2
-p24Y13`jaU'HrBBKj4VI[eGmL#cAFi`)1e4TKU0RV&GM!1Xq'eZjGTB%1aGL`RU%
-kB3IV[jX+EA%rV`rD3Qf21SiADYeJqDrT#5#+qS#Bf$aJ,3pSHDR3mP,d)%20DaL
-%IH@YSMra+BTN(Z+e`RDH#VY+DAeY&[VDM$DbhFhKY8YAe+mqY94k%PAVfSdlf-C
-RefkdL8d!a)[5M3Dk+pCqaU(I0p*4`0N!'G6"8+NcPrCkVGh0c4`e"!0P'R9IlJ1
-ri,9#"Mem39'L%pX@dph8p%KDAi'PTMp%-P[&lSY29Fl[[Mc#*i#3!1VA@mpZB-4
-3YrAXS`bK2XTCAZRb43cb[fqh&lKG+PKHLVBce(aLKi!U''9kEkel2cBUF-H+KEF
-AN`akM+'1U3(6'e""8XbYjCjpjI[RE1De3JBpcQF8a3GEFmUj6B8RQ$ENJ`i4SJI
-G#DHR4e'HC+J&($8%HjqpU)F2&1%1mQZ538p9X(e+-2'@U)S(YP*k9kSlJjp-3Kd
-e0C9,D'B(Ua9fjNLY+4fkY!jfL!NUbD#Gd5e-*4a1$P,@&,@,ckmUq)f$%eX-p@N
-qXDdIF$C1S6l6M6U`24$EXpNGlqYh1m62a[TkINm8EDY!,NUqfI30"KBdBmmY)ME
-allZTeiI4(G4laULHjqrKhmh8ZF(SB6T&B,5+ZV)Bh8GG&Sa@FabGqJ`BhFAcASj
-h1pdQ`-K223q-UURMMe%6GCm`UU&H2ND0e'A$5+%H(8CVH"hhmZqPG*F")iek3KK
-9dHd,M&C3IakMGG34a-K&RAH-PY#0#BaUUFq0d8VUNQ2832e'M*L6MG&DkPTLY)c
-Z,f$NTViG4LVee$"D6VF'-,U6qXSBHDK$Ke'!ZM%B,DEl("MG6jQ*NC-k3KLemRb
-Bmb$)[hG3&F3Sa22C9,Fa+Z&jJhqAFI`@RVq"IdIB0rkbMrrf"#UL3rV&reEF"Zb
-p0Xjrqad)%6Nrm2mFldfqbd0iE[+EmlCIGc-HMSM0XV+jbhj*434rb8G#S,[b&pk
-[jrfA([!I,DH[A$RLr,Gp1K&2m1qRU)G'p@6B4e"$A%mb$Tk)*pNRU&)ZiDFM#f`
-jq-pMPb0VCd@-RrMi'p0YIJ*q"FGh%I`B2dPYCqHN6Cf($fk'1SrLBbC[!A-G[%e
-&P-q&Mlpqa1'FAq()HJTHjqSkJG#S'AaQ2I4D)q%Ym2*H`P[i*[P3jb((h%[qJY#
-8KcX2Ieb,5L#IYB1pXJ8[6N%Ya-Qi"IkAd(jP1h,amilpl1F&qr(cBcTLrF,2I9D
-4d"2RKLhGHX,bVI`l$0mEUCk`r)jp)jdMU*ii0fcYeK2RKNHSRMJh%0dYirQ@IEP
-hMDGkiYb`MHS*r6hT&c6UCZDP4ZI*c"Y,)[+N9r0%f`pcTD8$pUYC)[*PAh0PFJk
-`hcm685"0i[p1DB+rC1Q!rD+G#21&5'RA(*!!i[rJfi3LKNZrjX!4MT(!hMParYZ
-[6)SB)8hLr`DH6qT!1mrrT!GM(16Pi,QRp@$`r9!4l0PIQC%Hl1+rLrX$YMj)#qC
-%qi9B%@6+N!#5qBAf@lmL4NQMjN4T`4aJ[piXiL,Teaa`KD1BlMr&qCpj88$%Xl)
-bI`!pcAlI[eH5HDGGa-@bX$Nak5[E,qq,Z%6DS3-2d(HRC"4km#"pf8T#i4rC0a@
-)'*h4!ar[Trc+2dMX&pM[')RBEHR!3r6Y04R5rU'd`9HdVkF3-8Efj5[fljGNlZ!
-3-9C@aRrlSK%4jVdldM(qflHTL,K89XCrqmSB%CG*[rD+%[k`I5q1L2(5+rlrq#k
-4I3'3!!Li$da10JIDYab*Z&a@aRrl+LF49dM,I)$-I98LVT3Qm9rDX$pUAm`PJQb
-TbcPdB!ZpJd&Q-JpF`r2bJ2F+-lH3!)QB+![c"r[I+mYFYbEL+NX(j%IlSp+'[9(
-lEMN49m[+r%,l!Md4Nf4PIU&p5k#)bG)`[c$jVRhQcN-4edUAI!&j`6Y8Dp%kb[f
-[G#"c+J-0FY8""1J*ZHcJD232*NhmCErIN!#jm9(%&1RA[*Pi[mDqeP*%UI5)rmR
-hlk30Hk[f*9-LYXV+I%Ml*Ld4MmM+q'rIibTLUUb-rrCPY5+ZNjIa2h0-VKR6T&q
-qB1*GE2Zk2"(ET%Rl"r)"Ih$SAHaqIbKcel+)FQRCI2MYfkBNTNZrjX2NIYU3!$d
-!YfR,V[Krl[f#j(dYQH["4Fb3!'lY$rhS$pLARSZB+5[c"qbEh8AF+2hb"a*cSAd
-9USKRT'YcBHBUIa'cT&pci5Um'YKl0E[T0qSACDll&I(i%2p0hTYmP`IF9bU2Z+I
-8j#hRCC*AqA!P0$Y-2-1XQk3e['V#j*@0bA&HLA[2EF'Dr31[iR0+FMk4Mr"X,5E
-[R%`ka61iU[Xl)rRQrmf&mK3G5r1,ALeZmfZ1aDrN2PrmEKRj#Fmbr$)[DrpkVTd
-VRCQr62rK'rd#IPhr0F()KDYb'hjYa131f*)i[h+!AppG4(hVMh0ZmJlQRh`iqB6
-[CXePTNq@e$GkLrkhqh6cC$AqMAP(BY,(JIG-['VE0`bE,l[a&dcr&qr!Zi!PTDG
-m5%0T9DHjrc0+Q*F6bh2Q#01[0hPSlQfDFm8f["hB0#A1a`*$mcE$S9SqfrPC)+h
-JSlaLVb)jhbAmq3)$cSJ,IRdY'%),T6AqI)*AKC4A"KcpQL&@TE5'9`Nr+,GYb"#
-k,F1VT%mXEjRRKZD&R(E9#0K[J*0B*+haJkV3%RS[HTBe,bbZVeeD9UdePXfD[@b
-!9qEHSPQ(XkH1iE9,9p5[*N@3!',5G@`FV'2-JZ@e5iY,CQVPXce6LLY6"CPhVbI
-Ub+Y4h#YUbhaRHd(#e*PN2fTJ4)8'3"r-V[6eil%-2bTG[SK"rQGkmQLQ(klU@TM
-`!YkU5!"H3[Ek)QTI35E2%hANeqQk$aTTP1Q$r#!ZLJPmd`6`Z"a9F*c*E&H9cq#
-rJ4G2*`+VYe@iUSe`9$$)*14`eDVHVLla)lMUae&#IN1km(m0$3T0B@0$9P-Z8&"
-$!*!901%!N"''!!!b6J#3!aB!"J#r68e38N0A588"!+Z[LaLY'C)V!!!V'3!!TS!
-!!!IK!!!2jBcE3Ki!N!DS#3h!e@8Q@cIpc'BVffaPjc8JE0eXhA66c6CYhIMpK+f
-Gc*0jQmTdVmI1*h[#$Nrah@CD+eZIi,ZkPG#pNNf[h16S*TX0pNSfBEF*Zhf-E0T
-Y`MEGM1`RqbKKK*&pj2D4hib`c3MEM'c#b$2#0KRXBq3Bf8mf)i``mTYX`XLa)jZ
-4hib`&EKE*r9fK'dfXh@[arB6'Q'E(([#0VP0IKrCj$B!fF!%ViN&E1+"!b!!X,J
-2B"&qKD(qRek*VX*,kr%@c3d3@'@C"pDB9M@mlEH*kcU(*0[Dh@DRdpBZB!f(`qQ
-bG63h)S8'IS)AlYfi(Grjr[BC!--$!+DCS0dp,f'0IEdUDYN+PK%26,0JKEJD+ZJ
-j0P39M@fVLSkS`C!!lNPXII%(kYm"EF-!Y"k@S!rV6"hTKfQ(Yd+XrhGrLSi-`Bb
-4Z6$VAMh$3$mBqNpFL9S1B&06pc%%+-+6$Y5M69U#[8X'P8Fqp'09+M&ITrS%qDT
-k$lZq('!D!X0L8"0)*0*P%JP#JkEHR6c5f,H2(9Z3!+&%i`J'*$NicUj#+Kdj,Ja
-NcQ0"`5SmS#j(jEDjM5KFBkX[X0'Vh#Rd[-,dqP$)reFp2!ZUZRURXj82`1%*bVe
-m!!k(Xl8TAkHdeGGPE0i8#LS4+T(l04b1eJC1!%H(E58IS+mZYqX"i'X1*Dc)I!#
-1F,HrUk!2Cf06AKrK5#mRJ'00BqFD`CaVVGl4BE5pefBb2DC)FUM0XXR%"H"3QH9
-R$IN(4iJEd0I31-J,$X(Fr9qGP@FiRV89hS8F6LNX5riR$8Rf055&H3%FmRKRmhf
-PKSebD#M(d`RbJN-`hr9YYd+$(#i[Q[fRd@PV+rLKFPUN-'(49TV4TH9KRSD6XLD
-GDChPSa`@CrVD8D*%lYGiih!IFh!$R'PE3iZad!q(Xb2I$rk(`kfcE,aIiih$IF6
-abZ%q8YNEKj[MH1P`#a`6$VI3e`Q(Qq0ikA!IF2c6i6jZb'Z(QqHBF,J2-0ikh"`
-((m$KdZ!%10-1Aq$pYFDSTHkK-bej0B%4*$HT*LC`MZ2Pj#cdBf*bjMPH6*J(('m
-R6)j$CFkj35ebS2!,eP0Yp[['EGa0are%)C3Mf08ccY(@eC2R+(%mqUfIDDV$4VF
-81!$aYiQRa@i`*Ik&!bH-Ipc$6+BFILNF0YU#Qd)qrjhZTK@0Xpll'5j!ArrR'E)
-H,qF9Ah$N*fGHCpQ*&aQAf86SDZL'#ql6&"(FL4&%86+G)Y+5-c$PPhT`&HN"6V-
-!ec``1@(PSQr!J&eTY,2La6#65+CcXSHZif"m#`lLmJS"EH*@*#prEE'RR8M[186
-%DY!@*djkPJ&mD!3[XMfDhFF%+K!D"*RL-1h6+m'PBG2Y"PeE3RkmK`C1Z)cRQPm
-G)")B,jFl+3%,"$hTDBH2h9M2+$piVBCpa4qH)G)bV,Q88UM(f*2!@#H933d8Lk+
-)(N$NB@L!'-kI"q2[MGLrlr))0)#recJD'VKdQ8HJJ5QS!G(@B9rVEKCp!GRIkr'
-+[!S0'-VT,,ci'al",#`Ee3!DAr(e()J4E"4IB3jFL(-(jS!GK1PLFTA"h4ZLEPe
-FjC8mAL8XCUVC(AmNpYAAmA`ikkX1cSH+2LX2`*ra#))Um"e9@PcTrZf0d[kPHjM
--lrd#IZ08!c2(0)#c3*%8RcHY!Mk+"QD0D3#cYdB"Rd8$cZ!@Vq,d5i%)0d8$D$H
-U(rU"qYAZCZ-GFm!ak"MpNUX,2J`Vm*+1A$A'KGQGbkb$-+@Q&Qm)Q"f'LPpdirH
-6hBPV9X`2iEd6S&ZUTh8a(iIb%dHYJeqUaGaQkk!`Qj,Xq(D+jA2@`ChcDBjFrI9
-kc1r(lblNUd!i,@jH6h,l0SAmAQ1$ej[EIH#@"2@eK2mL!Sa+p[m`*BR4+-8rLQM
-Gk5GemcMGfLq5c-(Hb,pa9f!N0rl)31IGcIPrm@55DdQFP!LI(42kEFVDc$X$QNf
-5,'m1brJA1ra`Pc+M#"fq@C!![AAfCTBA&1[@K515mTr"`J1)5RcCJBdl1[9'ljf
-!STpc3IT,+QkpYm'2L4p49@L5Ek`m,S,[Uc3RAB[U8[),q$qNmaJ23E5MrQBYf8N
-q*F6SD0Uc(k$2M0I9IhmYKBF5e4-kd)#!KA$13aa22!$Y#%LKi`KdNEj!mpaKXcp
-aE*6M)AAqXr00HP4mC5IEjYX[$j(P"RmPrMN(!qN$)D6JZYB-Q"9UTaYGT-QpaP@
-&CjGkK+dq-GGFY3(Qi,'5jK`%PZ+4lFT2RJXI`D1,jXVUJHlcXq8jX3RS82d+c@Q
-h3bFH,p#FS3c@!8bKGD#P'[!GJ6R-TEI["Gb*QVZ$jZbVS"pcKfKZkKEi)ZCq3(-
-I(kBmaKM0Z@r!0c&hK1D#Tq%SjYK-A[%(q$(!I-EGGJ4qKVR[d9a2&jc&,QkQ19m
-#cZ(JB+`P0q!L`))@*UE*F!9J)H[Pqlj-8%8,f@*Vl5j5LVR2Xh&cR-a%&H'V5KL
-Rk%E%SVY[)DJZXhYX"Dl-U34l[(,%L0S+qi)"I6V[m)APXY4'F(UG,Th[N!#8J#q
-`)9bD,YBBM5K5@02Sm8@#LVST')KSeNM+"Qp%Abr,APc)FdU4EVc2bNbL6cIBJKk
-[h4[3CCpaB0G53+A*aF`dGbUGaYEBQKaBE"*pR#M0NAfSU*LQF"ZHA8rak(%&1%[
-$YM8ck8PdAcH0NGhGCGG5jIm2!*!$$J#h-UICjpE,cTl@Q6P)'h4ZhfZJVCaH([I
-Xj(63@@G(`e221MbR[R(m9ei0Y%EfpMESb$&b@h,l*IX)IieXXXQaMJ`ff8HfNAd
-qH5lC4ijI*pRN0RPfjA@5fek%GejQ%Ti(h#$CHTcL+cZpr%f9MfK2"M`b@Sk-@!"
-N!j2eJ2&!RCHP6pH$##%-[p-4qZ%hi(FKj"VJ0`pqhd2jD#(bS0NPpBT[E90&Jfj
-BHh%aU[Mp&"b',a(mAS!@`AmH([)&3V-,IGeQK@Ri%2jJVrMdI8mY$[qbp5#DJaI
-8fLRHffJ@V@maI,NBkMYr%'pkqFU@TVU+e9UlS4LDDUTQ[+L"S2@9eDq2SIP9Id9
-lE`@T!3SD$1Lhb"hX(d*,8"lqU(+JIbm$4!RHJ8Xm@`D+Z+%"Vc+rqaH%*Y)H&#m
-ZQdcUV@aSm&Bd@BUPk@(&k-A2HXl$cp(I,X$Ehi8TlrV`UZKqP"pPTCbeB5HT"Dq
-b5#dN0Z&9h4&HY`Dr[I6l8XL9HRV69+$3m0[Be1Jpp#@T$rT&kSGq,IS!YH$lm&@
-HQi#$aH1ZcGYFT4KKI"&&LY,F+QXRlGFiK*H2)pq9eB8Ye3JS2K@i0P4lrpSI,-I
-E6#[D6M,)`e!,ka@VFaL3!-EZlfcJU#5$aM(8m[VehXCSf0*#DZ9Km2kI+Mei@hh
-$kKU53AN-G6c3VaNd$a$05RfSeNFL8'ZVGfd0bD"mhU%Qbqr0GZJAMrbFG`JbU)"
-hU'S0D*5A-(ki3m'RTr-133B98ZDKI-A[Vr5PqEYRkMYra(h0eDh0*)1+''UKiJp
-Ti65ZJeV-8)YpRDU[+ihVS*B`e"++UNHY*+b$@QUM"KA6e!+pAk+@-G3LAe"6`kP
-+"e((fkKk++3G3beRU'8q3e8XY3fSG!6C3Ch!Q3H6Lq%laVb*$,A!V`8#'CSlU*-
-iAi%+C)!CiqY*[%1UBHM'X3j0CUMMeCk)%[Dh48#F$f-lU0rJ,!pS3G@-YUI+h62
-e[9dfkRZld-QFH3%0+JdVS@4VR9URF!je+ZD4eJbM6Z8FkY4-5cG5-T4!2B8VLYB
-4eJheU+*-Xe&$%CLBXkL[#Y4AdDQmVd(GecADecMUDAaZ#1SGZENKMMUGD`1JjZD
-'11VT[%-K*3ZD3$f$-bqNqk1J$KRQa9(2j"`+pBEplF1+2)4D`@X0kfeCLA93Cc$
-8dSKLQ+S@$ZM$Z!lU@Ca$)*'qM"!jU'Gc[KUq%5B-SFlNI398AmKrP%2Rf+LU,`U
-G(81GaCPRU#'pqcqD&dFpPl2"8#0kTV-1kQbZ+)DZTh9b%(@1M@ST@G&c81Ib[TT
-J[d66,A*3jr&D-e20%1TjR1@M$8UJcZFGLNEm-)PQ1r5D3(d09A+@GkZ'#EC5KZ9
-ae!8ae$BVUbKae)8FGE1K4#,U##%Fe%A%Z!0828*m,l1bFaLerifRAf+S*!1q%d@
-&D6iFd$T5S'K28D2&Di8-Z)A8I5RZ8+dXLD!["d5($S$,+&#$@[JSkK+'@J5Sd0S
-XAq1ShcaB+k!Z'U[e3SCD#+LE-`k4JhS43md2qCING#L1HM'[e9!le*jMY5jPU#@
-QdUh1piddDFqdVLU1#KQdM+'@QPT(*aJ1`56hS-*A4+f[S%XimhT'kH#JAXVlfUZ
-DiH5-0i4k'GGbF(T'41J3kZA,UAS9QTCIdp1irGAc[SqBjT(-FSlDfkd%-pAfEhV
-QG)j+-PAJde-1pCS,`1f"hKj"hVh[9fma9*TC`@U&HFJ2e[Y)XIhDeArLYC+-Pp9
-D&!f$NH)I3GfpGrYXAL[*A"(VN!$2V`D5[GfplpNIf4f#6(8-eHU0J(F`M2U['@G
-b9*+TBDMP)FAA#9Uq3!QEfK$`%hrrc9D'5M-V'HS%'c9Clq1AGIq@SG*-,H03362
-aSG2Ld&qpm(+EjC!!U@1ePT'qCRLdHppcTpKXJ-b9$,@%XL&G,f!9#p4LY%U`h0$
-#k5QUAfYl`QBjC&Ec'583$P&h)`P,PHkJjY9cpI)4mQ68UrAG"PiVbDaKIFf2J*!
-!Cr5erpG2ri5MNXaDZkpJc5R"G&qVjdd5qMS*0I!1C955SFjpc%D&c&9mfJ$Q@@S
-S2BN16!#0-Ei5cb'*frrSVJ#[P@5D@)FQHr@`Ak0V)N&B[M(!8rNB[Rp'hc-FP@5
-D14Z#'KMIkF%"ZRP!p28!DQ%G+SaQj)4ShJG,Z6E3c$U1'[#&V66a3*8VhV49'6,
-VBeUH3Hl2Rck9GiKN@[QdiGF-XJF`-QhXHhDMQ"XfSJeaKcJY+3jIVlEp)G8!8b6
-,mVMAHmh!TX)BkXB"Gh0-8DlpH#iIDDb$HYf!5c&@DaY$,GLX`#E&-3jYLVQEafG
-PjH00K@aIiaaU(h$,a[VULcNLac[NGrbKc$`83e86MXJ`V)-Di&X4e&F1UYhUX&3
-kU"em!S!Y'a9f$M)63+HB!$T4*p2A!VUEPTPI(pfe3m`S1j!!aP8CpQbJ5HPD*mh
-m!dFPQHYM%i#Qqe)6`'k[FM,AFT,TiK0EFhVqTl9Ulrc0RPmK%q4XU1i'8Fl-3`0
-69)MA@N1f@$+e$U#''@TT95359*Z9B&GbXKP!e4PUZEGj4BZP"@(81e+bJaTKU#8
-0LUp,k4KTNS0k!d-YipY[+r6KiF&"0@)ZK3Nl+HS`df(LHP(-ALmLNk1'93Z%dPS
-!Qb*(82rj,G[T)4Q,cj5!k%pE8HMaVHHem%Q8C+*FKjL2-J,lj)Glrm&3DDDES8k
-dR4i9"QhP%2VMSAFEHDdNXrQJ@kBB'4qPHYjFi6I-46d-YEKY&2E*&bDmc$Y%-Vh
-(R@q'5M0Ef,444TbHL!RVGX0,+FlFF12!e$Zf&A'6lGU5@P-lBS1ehXbh-*[UeVD
-dMLa'`QEN8qY`(pZ-I'SGZX@HE)+`'D@N2B!I2cq(+`V*E'8F+Q9pEG15Zd"lmPr
-`m`j""[8ae!)$YQbbfalj,f`AU0[40P4!Q8HR+'JTDHeKEIMhfaI`[N)'hFUC"cY
-B)61p*Z)`lcE(QIYbHq"fX3N89*9MQd"h-$C3Cbkc2H$XEGc*8)Q6UTYYG#1`GfL
-rC-p%6bQ[&6,SVZ-ZHmaah-ilC)$mCrFELQlm(Um9-ZKZfj[Ap'M'4`%&YldSNVQ
-(+`VdP66*)2[YKe(I2$!"pj'[53EGbe",1'V%PjcB"MLdBcRE`J6VVeC9r,#MFd4
-5qL0r$D'qqRT[,FhFap@,eCTQ`l6Vh`!G!P553II(GMF9bdSC-)llmJ"$,9$"T4c
-eKq+S1aPUiHDXUcb)qZ$(U0QpMIM@d82a$KhE%hdi`BB[pTA4lDqMHNm4I(JaI8f
-""Ffi1LML6[lr&MUrB"5Q8cK''R92-'VLHChrVkIZ18Ch85A%U*9kRaJe8-mDSb$
-(@8Ip9ia#2,qDih95,`FMjJ9M9%2h)$$UT[-Z4L[TKJ0'&Tfe-6,TT)j4K0Ga!rq
-rK[Va'+fP$MY'Pp00&Sa@d(d4M&E4M3+-VU!l(4K9dHd6M0C6KaHMkkR2Jj&"r31
--'UN2MY'9G(m"SfUkeB&4P%l['0A4E3L-DZNZ"8CGe2("b%Xh66"US5ie4X[TEJa
-'ee#'BV5B6XNB+6ar(HI""[lr2UU'''hNq898L6(Da22Am[pAFrbVH,kGrfpMrcd
-&`cVJ6P%LlT!!KHN!lXBp`1*c%cVJHJXLq[MrSr`rbRZElr)3RY[mjV`GdGqF4b"
-LZba-If'[M,aMj%RSJ1[%L,LArpp"[C84AA%G4K&ErdpAj$PkFKR[[a4K[KrhCmJ
-RG#$R#iUiKrhe)!pakbSmHFhl8He"RZ,hReRSb@YkUiZraB6IrpPE6hjB'+pJ2k$
-PHI)H)fpEX9VbQMF"AKQS@ar"FcfRVQprkNG8hBb`1kZZKp,GZ@V,lp!i9b02HKl
-PZETmb8XSrc1185GHEK$i3aJTPMda8F`$"pm3ScVJ[X8NJU$,`HD"FJpjPfeT3JI
-Fel9%&%ZAG1"qDB,rkqL"qfkDL"+CQ%m`V!1M,q'*+*@'kF!8cbR!iQ8*(A$I0K3
-"VSjN53Im2*r5!ar2Ikd,ChJUL+ee5"G'Akm8-9kDT!X2m1m5rS'V%p+#qG&pTe4
-%ZHc-Ah4IRK8a36Se2dS,jJ,h6@%4pL[LmUqjB*D([&0rkD!1j2EG46`N1r-2d%l
-frFKq5ZieF4'6T'2cBp+2GYq*&h'5p%-20Y1AQ@38ZY"$hhk582K-lL8!)LD2k8)
-[lk[mbPp)lLHi,q1)H$LT"ahdj8%CdRkMY-'(G'q!%!(ATNM#I-M8RNVZUJX4*m[
-1G-#pdd2%&0QC$VLAPiLB+M[6!IH@&K(%TCD$k8$59hD[Sa%a6CUP!qS*Rb"hpik
-)8f9Rmk&lbC!!L00NCcVJhUBN!LjANjcj",Rhm8AF+Ph5!@R$RUTlICD)dk8IHR!
-h[6T!CM)I"(KH([$HBZkq-"&R5-Ima06lDVR,d85FQG3$qG'HUV4K2p@p$8i%fAk
-@Q[Q,lV9h)QE)c[a&phir%@G*arc&T"kiPaQ+1&[Dj"[)&rb#h-f0)QC+`qE%j,X
-hlK@9)Xk4*ZP!kPdpDF2qURYENiMEC@HqSRXhUBKCXM-GF#pK&A'Zl%`(h0YQ4GK
-ACd[-G#"h$+iGFk4K1T!!I*rE[E42a)h5TId#qB#IH24plT52P,Y6@F4FkGRFq2P
-EUL6Q5F0d),@A0QBI`1hCXL`G1,T[NVS6*RFPZ)MjdUjpT"2qJAX2ZSK+fCPri&l
-i,Q+"0%`(N[1LHcfTL!HPEI0LlUCr%IE9JI)`Rj(H%acc'4ArPhHUfLFT5X0m4Kc
-!j2$'Fa*ki&kD,1)frYr9J46r8lcrIll,)qj5YIR-q6V#-lJYr3Y$pr`6ZT[JQlb
-%CpIK6F#5QBGj4QpiGhPfJD0RUEfla$dcmK1HjIKPhjRrb3Ljj+Yj3AkL@rCmpjP
-q!Em@I8+`EdT[q(8R*TIqcNR`Ua$ipF@PcKGq0BIppclMVrd1qB5riFaRYJq4dVR
-mN!"rb4Fqe%A5'CeclP6%B4`"GX`De$P$l9"l2Q2BaE)F[m(ffm6Ge`lI5NbP@jh
-[qh5d@(V#4j-2h(XYRq#ElBID[12q*ViIl`6@c%h`VY681MVKJ+fJkrJXNel-Fr)
-+hcSeekh$VF#QX`ra%Fk1Lhab64K#0mPUjVS8VmSSVd`i,MC(V#h5'PiPrD#LRM&
-$k*+aq5(P&mYEI+'aZD'`9cA$lP[G*#k9e[K"0DL@hLe1VJU2c`dV@jVU+PGVlC8
-0$GiXVlEarhBGq30eM'qU@p[55SSJa@6UZ(QdMX)QbqmGVB#&MCZXSk`ZE+P'32'
-TZ@,X1mj6rDL(8IAcIYMlP-NkbZ[AHaZMB8X,UD-%XA8[a60J@,1Z"k%'Xe,2p-2
-QHDSI9@ZDkLUmRa)fGP%j[R!k61@H'MLD`G03%c6j0q"hcDL&KdeIEeKY@M&#A%(
-q0$5T(4pp*$k#DedmXmNhT![r!b%K#d0A)&"bEfTPBh4c!*!C-3!1!@X!eJ#3!`%
-!!"SB!*!(&J#3!iB!!!%!rj!%!3#Xp*MlV4Q4cJ#3"3'M[!#3"M()!*!+0U&*&`!!:
diff --git a/gnu/usr.bin/cvs/macintosh/maccvs.rsrc.sit.hqx b/gnu/usr.bin/cvs/macintosh/maccvs.rsrc.sit.hqx
deleted file mode 100644
index 8b5b8dfe0c3..00000000000
--- a/gnu/usr.bin/cvs/macintosh/maccvs.rsrc.sit.hqx
+++ /dev/null
@@ -1,14 +0,0 @@
-(This file must be converted with BinHex 4.0)
-:$feKBf0fFbjbFh*M,R0TG!"6594%8dP8)3#3"!*E!*!%l,p6593K!!%!!!*EFNa
-KG3,r!*!$&[rr$3!,E@&MBhCc,R*cFQ-")mTJ!$9PbJ#3!i!!N!3"+qi1R+d!N"V
-rN!4bFh*M8P0&4!%!Um#*JDcYi3m!!!,1!*!'!G8!N!5ed!#3##))%3!)!$cFi3b
-Kcj0pmpAd3HjfE-CVb5I(RG%UGI`KVAa[[pEUH-IPG9`C'53PC9#Q6f5+&)m6f%5
-%$,B2PA@Nk%XlV2H"NJ-ZbeDiQhUf5Y@pIZ[3TQ9ddh2D[2h+eUK[rHbfjqBDIeM
-P2M@GeT%hfc'pbIGI'cp1-h-GrXf#C9)pII0(SA,,VQdM15pQElr#VbM6&0$i3h#
-qe))emidrbQReS3jp8Q0eaX*18,$6``8R*[I'I3+GNfp*lUkQeh4fAe8X0$4+-Hq
-28`3PNSCardJkc3`P*rK,Y0D1(['aH@C#PZ3C4%C55(Vk8*`CM6#FNL8bZ8KXY@Q
-S8$+A1#Xc`P*a5PSi)LTADG@UIDK!3SS6`AV)QC,)E)mBDKh!B8)c1$2bfX4jFNE
-R`3bhjLb6Te1YZl[56#S'dI!hBPjh+M)MR1(+BFiU5@H$9TC+UqMG-T+c-S*CrIY
-(8QKQjpE*S4a9p3X'3kec'YZ!$XNf0p(T60mhfb20ZJE,&XpIkGbd'!$)ZH%SJ`!
-&3dNp3kelY%q#PVALkpA54frpEXJ0l9rC10C4+23#6mJIk14SqF(f[A5A`VEGcQh
-[F+Ab1cq3!)KbdK[3$Hh'9-l@hSKZD$Xk9SG0!J"093!!:
diff --git a/gnu/usr.bin/cvs/macintosh/maccvs165.patch b/gnu/usr.bin/cvs/macintosh/maccvs165.patch
deleted file mode 100644
index 68f7733ca74..00000000000
--- a/gnu/usr.bin/cvs/macintosh/maccvs165.patch
+++ /dev/null
@@ -1,2509 +0,0 @@
-diff -r -C 2 -P base/cvs-1.6.5/ChangeLog cvs-1.6.5/ChangeLog
-*** base/cvs-1.6.5/ChangeLog Tue Jan 9 06:20:05 1996
---- cvs-1.6.5/ChangeLog Wed Jan 10 13:41:54 1996
-***************
-*** 1,2 ****
---- 1,12 ----
-+ Tue Jan 9 12:39:22 1995 Mike Ladwig <mike@twinpeaks.prc.com>
-+
-+ * Port of CVS (CVS 1.6.5 snapshot 1/9/96) to MacOS 7.x
-+ * Virtually all "cvs base" changes are to wrap filesystem calls
-+ (e.g. CVS_FOPEN) to allow for pathname changes and permission
-+ parameter removal
-+ * Mac-specific code (rcmd port, fs stuff) all in 'macintosh' subdir
-+ * Build requires CW GUSI 1.6.4 and CodeWarrier 7
-+ * 'release' doesn't work, due to cvs implementation approach
-+
- Mon Jan 8 11:42:40 1996 Jim Kingdon <kingdon@harvey.cyclic.com>
-
-diff -r -C 2 -P base/cvs-1.6.5/lib/regex.c cvs-1.6.5/lib/regex.c
-*** base/cvs-1.6.5/lib/regex.c Tue Oct 10 07:20:24 1995
---- cvs-1.6.5/lib/regex.c Tue Jan 9 05:33:05 1996
-***************
-*** 231,236 ****
---- 231,240 ----
- #define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
-
-+ #ifndef MAX
- #define MAX(a, b) ((a) > (b) ? (a) : (b))
-+ #endif
-+ #ifndef MIN
- #define MIN(a, b) ((a) < (b) ? (a) : (b))
-+ #endif
-
- typedef char boolean;
-diff -r -C 2 -P base/cvs-1.6.5/lib/save-cwd.c cvs-1.6.5/lib/save-cwd.c
-*** base/cvs-1.6.5/lib/save-cwd.c Sat Oct 28 07:20:10 1995
---- cvs-1.6.5/lib/save-cwd.c Wed Jan 10 13:22:50 1996
-***************
-*** 122,126 ****
- }
- }
-! else if (chdir (cwd->name) < 0)
- {
- error (0, errno, "%s", cwd->name);
---- 122,126 ----
- }
- }
-! else if (CVS_CHDIR (cwd->name) < 0)
- {
- error (0, errno, "%s", cwd->name);
-diff -r -C 2 -P base/cvs-1.6.5/lib/system.h cvs-1.6.5/lib/system.h
-*** base/cvs-1.6.5/lib/system.h Thu Jan 4 06:20:14 1996
---- cvs-1.6.5/lib/system.h Tue Jan 9 05:33:06 1996
-***************
-*** 434,443 ****
- #endif
-
-! /* Under MS-DOS and its derivatives (like Windows NT), mkdir takes only one
-! argument; permission is handled very differently on those systems than in
-! in Unix. So we leave such systems a hook on which they can hang their
-! own definitions. */
- #ifndef CVS_MKDIR
- #define CVS_MKDIR mkdir
- #endif
-
---- 434,483 ----
- #endif
-
-! /* Under non-UNIX operating systems (MS-DOS, WinNT, MacOS), many filesystem
-! calls take only one argument; permission is handled very differently on
-! those systems than in Unix. So we leave such systems a hook on which they
-! can hang their own definitions. */
- #ifndef CVS_MKDIR
- #define CVS_MKDIR mkdir
-+ #endif
-+
-+ #ifndef CVS_MKDIR
-+ #define CVS_MKDIR mkdir
-+ #endif
-+
-+ #ifndef CVS_OPEN
-+ #define CVS_OPEN open
-+ #endif
-+
-+ #ifndef CVS_CREAT
-+ #define CVS_CREAT creat
-+ #endif
-+
-+ #ifndef CVS_FOPEN
-+ #define CVS_FOPEN fopen
-+ #endif
-+
-+ #ifndef CVS_CHDIR
-+ #define CVS_CHDIR chdir
-+ #endif
-+
-+ #ifndef CVS_ACCESS
-+ #define CVS_ACCESS access
-+ #endif
-+
-+ #ifndef CVS_OPENDIR
-+ #define CVS_OPENDIR opendir
-+ #endif
-+
-+ #ifndef CVS_STAT
-+ #define CVS_STAT stat
-+ #endif
-+
-+ #ifndef CVS_RENAME
-+ #define CVS_RENAME rename
-+ #endif
-+
-+ #ifndef CVS_UNLINK
-+ #define CVS_UNLINK unlink
- #endif
-
-diff -r -C 2 -P base/cvs-1.6.5/src/add.c cvs-1.6.5/src/add.c
-*** base/cvs-1.6.5/src/add.c Thu Jan 4 06:20:24 1996
---- cvs-1.6.5/src/add.c Tue Jan 9 05:33:07 1996
-***************
-*** 381,385 ****
- if (save_cwd (&cwd))
- return (1);
-! if (chdir (dir) < 0)
- {
- error (0, errno, "cannot chdir to %s", dir);
---- 381,385 ----
- if (save_cwd (&cwd))
- return (1);
-! if (CVS_CHDIR (dir) < 0)
- {
- error (0, errno, "cannot chdir to %s", dir);
-diff -r -C 2 -P base/cvs-1.6.5/src/checkout.c cvs-1.6.5/src/checkout.c
-*** base/cvs-1.6.5/src/checkout.c Thu Jan 4 06:20:25 1996
---- cvs-1.6.5/src/checkout.c Tue Jan 9 05:33:07 1996
-***************
-*** 351,355 ****
-
- (void) CVS_MKDIR (where, 0777);
-! if (chdir (where) < 0)
- error (1, errno, "cannot chdir to %s", where);
- preload_update_dir = xstrdup (where);
---- 351,355 ----
-
- (void) CVS_MKDIR (where, 0777);
-! if (CVS_CHDIR (where) < 0)
- error (1, errno, "cannot chdir to %s", where);
- preload_update_dir = xstrdup (where);
-***************
-*** 402,406 ****
- *slash = '\0';
-
-! if (chdir (where) < 0)
- error (1, errno, "cannot chdir to %s", where);
-
---- 402,406 ----
- *slash = '\0';
-
-! if (CVS_CHDIR (where) < 0)
- error (1, errno, "cannot chdir to %s", where);
-
-***************
-*** 716,720 ****
- if (pipeout)
- {
-! if (chdir (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
---- 716,720 ----
- if (pipeout)
- {
-! if (CVS_CHDIR (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
-***************
-*** 855,859 ****
- *slash2 = '\0';
- (void) CVS_MKDIR (cp, 0777);
-! if (chdir (cp) < 0)
- {
- error (0, errno, "cannot chdir to %s", cp);
---- 855,859 ----
- *slash2 = '\0';
- (void) CVS_MKDIR (cp, 0777);
-! if (CVS_CHDIR (cp) < 0)
- {
- error (0, errno, "cannot chdir to %s", cp);
-***************
-*** 883,887 ****
- }
- (void) CVS_MKDIR (cp, 0777);
-! if (chdir (cp) < 0)
- {
- error (0, errno, "cannot chdir to %s", cp);
---- 883,887 ----
- }
- (void) CVS_MKDIR (cp, 0777);
-! if (CVS_CHDIR (cp) < 0)
- {
- error (0, errno, "cannot chdir to %s", cp);
-diff -r -C 2 -P base/cvs-1.6.5/src/client.c cvs-1.6.5/src/client.c
-*** base/cvs-1.6.5/src/client.c Tue Jan 9 06:20:21 1996
---- cvs-1.6.5/src/client.c Tue Jan 9 05:33:07 1996
-***************
-*** 375,382 ****
- error (1, 0, "premature end of file from server");
- }
--
-- if (c == '\n')
-- break;
-
- result[input_index++] = c;
- while (input_index + 1 >= result_size)
---- 375,382 ----
- error (1, 0, "premature end of file from server");
- }
-
-+ if (c == '\012')
-+ break;
-+
- result[input_index++] = c;
- while (input_index + 1 >= result_size)
-***************
-*** 691,697 ****
- "could not get working directory: %s", toplevel_wd);
-
-! if (chdir (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
-! if (chdir (dirname) < 0)
- {
- char *dir;
---- 691,697 ----
- "could not get working directory: %s", toplevel_wd);
-
-! if (CVS_CHDIR (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
-! if (CVS_CHDIR (dirname) < 0)
- {
- char *dir;
-***************
-*** 838,842 ****
- free (dir);
- /* Now it better work. */
-! if (chdir (dirname) < 0)
- error (1, errno, "could not chdir to %s", dirname);
- }
---- 838,842 ----
- free (dir);
- /* Now it better work. */
-! if (CVS_CHDIR (dirname) < 0)
- error (1, errno, "could not chdir to %s", dirname);
- }
-***************
-*** 1087,1091 ****
- bin = 0;
-
-! fd = open (temp_filename,
- O_WRONLY | O_CREAT | O_TRUNC | (bin ? OPEN_BINARY : 0),
- 0777);
---- 1087,1091 ----
- bin = 0;
-
-! fd = CVS_OPEN (temp_filename,
- O_WRONLY | O_CREAT | O_TRUNC | (bin ? OPEN_BINARY : 0),
- 0777);
-***************
-*** 1134,1138 ****
- convert_file (temp_filename, O_RDONLY | OPEN_BINARY,
- filename, O_WRONLY | O_CREAT | O_TRUNC);
-! if (unlink (temp_filename) < 0)
- error (0, errno, "warning: couldn't delete %s",
- temp_filename);
---- 1134,1138 ----
- convert_file (temp_filename, O_RDONLY | OPEN_BINARY,
- filename, O_WRONLY | O_CREAT | O_TRUNC);
-! if (CVS_UNLINK (temp_filename) < 0)
- error (0, errno, "warning: couldn't delete %s",
- temp_filename);
-***************
-*** 1156,1160 ****
- error (1, 0, "patch original file %s does not exist",
- short_pathname);
-! if (stat (temp_filename, &s) < 0)
- error (1, 1, "can't stat patch file %s", temp_filename);
- if (s.st_size == 0)
---- 1156,1160 ----
- error (1, 0, "patch original file %s does not exist",
- short_pathname);
-! if (CVS_STAT (temp_filename, &s) < 0)
- error (1, 1, "can't stat patch file %s", temp_filename);
- if (s.st_size == 0)
-***************
-*** 1227,1231 ****
- * way they were transmitted.
- */
-! e = fopen (filename, "r");
- if (e == NULL)
- error (1, errno, "could not open %s", short_pathname);
---- 1227,1231 ----
- * way they were transmitted.
- */
-! e = CVS_FOPEN (filename, "r");
- if (e == NULL)
- error (1, errno, "could not open %s", short_pathname);
-***************
-*** 1639,1643 ****
- if (toplevel_wd[0] != '\0')
- {
-! if (chdir (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- }
---- 1639,1643 ----
- if (toplevel_wd[0] != '\0')
- {
-! if (CVS_CHDIR (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- }
-***************
-*** 1685,1689 ****
- struct dirent *dp;
-
-! if ((dirp = opendir (dir)) == NULL)
- {
- if (! existence_error (errno))
---- 1685,1689 ----
- struct dirent *dp;
-
-! if ((dirp = CVS_OPENDIR (dir)) == NULL)
- {
- if (! existence_error (errno))
-***************
-*** 1742,1746 ****
- if (toplevel_wd[0] != '\0')
- {
-! if (chdir (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- }
---- 1742,1746 ----
- if (toplevel_wd[0] != '\0')
- {
-! if (CVS_CHDIR (toplevel_wd) < 0)
- error (1, errno, "could not chdir to %s", toplevel_wd);
- }
-***************
-*** 1828,1832 ****
- sprintf (adm_name, "%s/%s", dir, CVSADM_TAG);
-
-! f = fopen (adm_name, "r");
- if (f == NULL)
- {
---- 1828,1832 ----
- sprintf (adm_name, "%s/%s", dir, CVSADM_TAG);
-
-! f = CVS_FOPEN (adm_name, "r");
- if (f == NULL)
- {
-***************
-*** 1860,1864 ****
- sprintf (adm_name, "%s/%s", dir, CVSADM_CIPROG);
-
-! f = fopen (adm_name, "r");
- if (f == NULL)
- {
---- 1860,1864 ----
- sprintf (adm_name, "%s/%s", dir, CVSADM_CIPROG);
-
-! f = CVS_FOPEN (adm_name, "r");
- if (f == NULL)
- {
-***************
-*** 1895,1899 ****
- sprintf (adm_name, "%s/%s", dir, CVSADM_UPROG);
-
-! f = fopen (adm_name, "r");
- if (f == NULL)
- {
---- 1895,1899 ----
- sprintf (adm_name, "%s/%s", dir, CVSADM_UPROG);
-
-! f = CVS_FOPEN (adm_name, "r");
- if (f == NULL)
- {
-***************
-*** 3181,3185 ****
-
- /* Don't think we can assume fstat exists. */
-! if (stat (file, &sb) < 0)
- error (1, errno, "reading %s", short_pathname);
-
---- 3181,3185 ----
-
- /* Don't think we can assume fstat exists. */
-! if (CVS_STAT (file, &sb) < 0)
- error (1, errno, "reading %s", short_pathname);
-
-***************
-*** 3202,3206 ****
- bin = 0;
-
-! fd = open (file, O_RDONLY | (bin ? OPEN_BINARY : 0));
-
- if (fd < 0)
---- 3202,3206 ----
- bin = 0;
-
-! fd = CVS_OPEN (file, O_RDONLY | (bin ? OPEN_BINARY : 0));
-
- if (fd < 0)
-***************
-*** 3256,3260 ****
- the translation mode to created processes via environment
- variables, ick. */
-! fd = open (tempfile, O_RDONLY | OPEN_BINARY);
- if (fd < 0)
- error (1, errno, "reading %s", short_pathname);
---- 3256,3260 ----
- the translation mode to created processes via environment
- variables, ick. */
-! fd = CVS_OPEN (tempfile, O_RDONLY | OPEN_BINARY);
- if (fd < 0)
- error (1, errno, "reading %s", short_pathname);
-***************
-*** 3297,3301 ****
- if (converting)
- {
-! if (unlink (tempfile) < 0)
- error (0, errno,
- "warning: can't remove temp file %s", tempfile);
---- 3297,3301 ----
- if (converting)
- {
-! if (CVS_UNLINK (tempfile) < 0)
- error (0, errno,
- "warning: can't remove temp file %s", tempfile);
-***************
-*** 3800,3804 ****
- if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", CVSADM_NOTIFY);
-! if (unlink (CVSADM_NOTIFY) < 0)
- error (0, errno, "cannot remove %s", CVSADM_NOTIFY);
- return;
---- 3800,3804 ----
- if (fclose (fp) < 0)
- error (0, errno, "cannot close %s", CVSADM_NOTIFY);
-! if (CVS_UNLINK (CVSADM_NOTIFY) < 0)
- error (0, errno, "cannot remove %s", CVSADM_NOTIFY);
- return;
-***************
-*** 3845,3849 ****
- return;
- }
-! if (rename (CVSADM_NOTIFYTMP, CVSADM_NOTIFY) < 0)
- error (0, errno, "cannot rename %s to %s", CVSADM_NOTIFYTMP,
- CVSADM_NOTIFY);
---- 3845,3849 ----
- return;
- }
-! if (CVS_RENAME (CVSADM_NOTIFYTMP, CVSADM_NOTIFY) < 0)
- error (0, errno, "cannot rename %s to %s", CVSADM_NOTIFYTMP,
- CVSADM_NOTIFY);
-diff -r -C 2 -P base/cvs-1.6.5/src/commit.c cvs-1.6.5/src/commit.c
-*** base/cvs-1.6.5/src/commit.c Fri Jan 5 06:20:20 1996
---- cvs-1.6.5/src/commit.c Tue Jan 9 05:33:07 1996
-***************
-*** 297,301 ****
- error (1, 0, "cannot specify both a message and a log file");
-
-! if ((logfd = open (logfile, O_RDONLY | OPEN_BINARY)) < 0)
- error (1, errno, "cannot open log file %s", logfile);
-
---- 297,301 ----
- error (1, 0, "cannot specify both a message and a log file");
-
-! if ((logfd = CVS_OPEN (logfile, O_RDONLY | OPEN_BINARY)) < 0)
- error (1, errno, "cannot open log file %s", logfile);
-
-***************
-*** 1088,1092 ****
- FILE *fp;
-
-! if ((fp = fopen (CVSADM_CIPROG, "r")) != NULL)
- {
- char *line;
---- 1088,1092 ----
- FILE *fp;
-
-! if ((fp = CVS_FOPEN (CVSADM_CIPROG, "r")) != NULL)
- {
- char *line;
-***************
-*** 1414,1418 ****
- #ifdef DEATH_SUPPORT
- if (strcmp (rcs, tmp) != 0
-! && rename (rcs, tmp) == -1
- && (isreadable (rcs) || !isreadable (tmp)))
- {
---- 1414,1418 ----
- #ifdef DEATH_SUPPORT
- if (strcmp (rcs, tmp) != 0
-! && CVS_RENAME (rcs, tmp) == -1
- && (isreadable (rcs) || !isreadable (tmp)))
- {
-***************
-*** 1434,1438 ****
- #else /* No DEATH_SUPPORT */
-
-! if ((strcmp (rcs, tmp) == 0 || rename (rcs, tmp) != -1) ||
- (!isreadable (rcs) && isreadable (tmp)))
- {
---- 1434,1438 ----
- #else /* No DEATH_SUPPORT */
-
-! if ((strcmp (rcs, tmp) == 0 || CVS_RENAME (rcs, tmp) != -1) ||
- (!isreadable (rcs) && isreadable (tmp)))
- {
-***************
-*** 1589,1593 ****
-
- if (strcmp (oldfile, rcs) == 0
-! || rename (oldfile, rcs) != 0
- || isreadable (oldfile)
- || !isreadable (rcs))
---- 1589,1593 ----
-
- if (strcmp (oldfile, rcs) == 0
-! || CVS_RENAME (oldfile, rcs) != 0
- || isreadable (oldfile)
- || !isreadable (rcs))
-***************
-*** 1872,1876 ****
- struct stat sb;
-
-! if (stat (user, &sb) != -1)
- (void) chmod (rcs, (int) sb.st_mode & ~0222);
- }
---- 1872,1876 ----
- struct stat sb;
-
-! if (CVS_STAT (user, &sb) != -1)
- (void) chmod (rcs, (int) sb.st_mode & ~0222);
- }
-diff -r -C 2 -P base/cvs-1.6.5/src/create_adm.c cvs-1.6.5/src/create_adm.c
-*** base/cvs-1.6.5/src/create_adm.c Fri Sep 8 07:20:21 1995
---- cvs-1.6.5/src/create_adm.c Tue Jan 9 05:33:07 1996
-***************
-*** 66,70 ****
- else
- (void) strcpy (tmp, CVSADM_REP);
-! fout = fopen (tmp, "w+");
- if (fout == NULL)
- {
---- 66,70 ----
- else
- (void) strcpy (tmp, CVSADM_REP);
-! fout = CVS_FOPEN (tmp, "w+");
- if (fout == NULL)
- {
-***************
-*** 112,116 ****
- else
- (void) strcpy (tmp, CVSADM_ENT);
-! fout = fopen (tmp, "w+");
- if (fout == NULL)
- {
---- 112,116 ----
- else
- (void) strcpy (tmp, CVSADM_ENT);
-! fout = CVS_FOPEN (tmp, "w+");
- if (fout == NULL)
- {
-diff -r -C 2 -P base/cvs-1.6.5/src/cvs.h cvs-1.6.5/src/cvs.h
-*** base/cvs-1.6.5/src/cvs.h Wed Jan 3 06:20:23 1996
---- cvs-1.6.5/src/cvs.h Tue Jan 9 05:33:06 1996
-***************
-*** 231,236 ****
---- 231,241 ----
- #endif
-
-+ #ifndef FALSE
- #define FALSE 0
-+ #endif
-+
-+ #ifndef TRUE
- #define TRUE 1
-+ #endif
-
- /*
-diff -r -C 2 -P base/cvs-1.6.5/src/diff.c cvs-1.6.5/src/diff.c
-*** base/cvs-1.6.5/src/diff.c Thu Jan 4 06:20:27 1996
---- cvs-1.6.5/src/diff.c Tue Jan 9 05:33:07 1996
-***************
-*** 373,377 ****
- if (run_exec (RUN_TTY, tmpnam (tmp), RUN_TTY, RUN_REALLY) == -1)
- {
-! (void) unlink (tmp);
- error (1, errno, "fork failed during checkout of %s",
- vers->srcfile->path);
---- 373,377 ----
- if (run_exec (RUN_TTY, tmpnam (tmp), RUN_TTY, RUN_REALLY) == -1)
- {
-! (void) CVS_UNLINK (tmp);
- error (1, errno, "fork failed during checkout of %s",
- vers->srcfile->path);
-***************
-*** 423,427 ****
-
- if (empty_file == DIFF_REMOVED)
-! (void) unlink (tmp);
-
- (void) fflush (stdout);
---- 423,427 ----
-
- if (empty_file == DIFF_REMOVED)
-! (void) CVS_UNLINK (tmp);
-
- (void) fflush (stdout);
-***************
-*** 611,620 ****
- if (xcmp (file, tmp) == 0)
- {
-! (void) unlink (tmp);
- return (1);
- }
- break;
- case -1: /* fork failed */
-! (void) unlink (tmp);
- error (1, errno, "fork failed during checkout of %s",
- vers->srcfile->path);
---- 611,620 ----
- if (xcmp (file, tmp) == 0)
- {
-! (void) CVS_UNLINK (tmp);
- return (1);
- }
- break;
- case -1: /* fork failed */
-! (void) CVS_UNLINK (tmp);
- error (1, errno, "fork failed during checkout of %s",
- vers->srcfile->path);
-***************
-*** 622,626 ****
- break;
- }
-! (void) unlink (tmp);
- return (0);
- }
---- 622,626 ----
- break;
- }
-! (void) CVS_UNLINK (tmp);
- return (0);
- }
-diff -r -C 2 -P base/cvs-1.6.5/src/edit.c cvs-1.6.5/src/edit.c
-*** base/cvs-1.6.5/src/edit.c Thu Jan 4 06:20:27 1996
---- cvs-1.6.5/src/edit.c Tue Jan 9 05:33:07 1996
-***************
-*** 180,184 ****
- is most sensible. */
-
-! fp = fopen (CVSADM_NOTIFY, "r");
- if (fp == NULL)
- {
---- 180,184 ----
- is most sensible. */
-
-! fp = CVS_FOPEN (CVSADM_NOTIFY, "r");
- if (fp == NULL)
- {
-***************
-*** 225,229 ****
- error (0, errno, "cannot close %s", CVSADM_NOTIFY);
-
-! if (unlink (CVSADM_NOTIFY) < 0)
- error (0, errno, "cannot remove %s", CVSADM_NOTIFY);
-
---- 225,229 ----
- error (0, errno, "cannot close %s", CVSADM_NOTIFY);
-
-! if (CVS_UNLINK (CVSADM_NOTIFY) < 0)
- error (0, errno, "cannot remove %s", CVSADM_NOTIFY);
-
-***************
-*** 810,814 ****
- is most sensible. */
-
-! fp = fopen (CVSADM_NOTIFY, "r");
- if (fp == NULL)
- {
---- 810,814 ----
- is most sensible. */
-
-! fp = CVS_FOPEN (CVSADM_NOTIFY, "r");
- if (fp == NULL)
- {
-diff -r -C 2 -P base/cvs-1.6.5/src/entries.c cvs-1.6.5/src/entries.c
-*** base/cvs-1.6.5/src/entries.c Thu Jan 4 06:20:28 1996
---- cvs-1.6.5/src/entries.c Tue Jan 9 05:33:07 1996
-***************
-*** 280,284 ****
- {
- struct stat sb;
-! if (strlen (ts) > 30 && stat (user, &sb) == 0)
- {
- char *c = ctime (&sb.st_mtime);
---- 280,284 ----
- {
- struct stat sb;
-! if (strlen (ts) > 30 && CVS_STAT (user, &sb) == 0)
- {
- char *c = ctime (&sb.st_mtime);
-***************
-*** 373,377 ****
- }
-
-! fpin = fopen (CVSADM_ENT, "r");
- if (fpin == NULL)
- error (0, errno, "cannot open %s for reading", CVSADM_ENT);
---- 373,377 ----
- }
-
-! fpin = CVS_FOPEN (CVSADM_ENT, "r");
- if (fpin == NULL)
- error (0, errno, "cannot open %s for reading", CVSADM_ENT);
-***************
-*** 384,390 ****
-
- fclose (fpin);
- }
-
-! fpin = fopen (CVSADM_ENTLOG, "r");
- if (fpin != NULL)
- {
---- 384,391 ----
-
- fclose (fpin);
-+ fpin = NULL;
- }
-
-! fpin = CVS_FOPEN (CVSADM_ENTLOG, "r");
- if (fpin != NULL)
- {
-***************
-*** 395,398 ****
---- 396,400 ----
- do_rewrite = 1;
- fclose (fpin);
-+ fpin = NULL;
- }
-
-***************
-*** 528,532 ****
- if (datep)
- *datep = (char *) NULL;
-! fp = fopen (CVSADM_TAG, "r");
- if (fp)
- {
---- 530,534 ----
- if (datep)
- *datep = (char *) NULL;
-! fp = CVS_FOPEN (CVSADM_TAG, "r");
- if (fp)
- {
-diff -r -C 2 -P base/cvs-1.6.5/src/error.c cvs-1.6.5/src/error.c
-*** base/cvs-1.6.5/src/error.c Sat Dec 16 06:20:29 1995
---- cvs-1.6.5/src/error.c Tue Jan 9 05:33:07 1996
-***************
-*** 67,71 ****
---- 67,73 ----
- #endif /* STDC_HEADERS */
-
-+ #ifndef macintosh
- extern char *strerror ();
-+ #endif
-
- typedef void (*fn_returning_void) PROTO((void));
-diff -r -C 2 -P base/cvs-1.6.5/src/fileattr.c cvs-1.6.5/src/fileattr.c
-*** base/cvs-1.6.5/src/fileattr.c Fri Dec 22 06:20:27 1995
---- cvs-1.6.5/src/fileattr.c Tue Jan 9 05:33:07 1996
-***************
-*** 79,83 ****
-
- attr_read_attempted = 1;
-! fp = fopen (fname, "r");
- if (fp == NULL)
- {
---- 79,83 ----
-
- attr_read_attempted = 1;
-! fp = CVS_FOPEN (fname, "r");
- if (fp == NULL)
- {
-***************
-*** 440,444 ****
-
- omask = umask (cvsumask);
-! fp = fopen (fname, "w");
- if (fp == NULL)
- {
---- 440,444 ----
-
- omask = umask (cvsumask);
-! fp = CVS_FOPEN (fname, "w");
- if (fp == NULL)
- {
-***************
-*** 465,469 ****
- free (repname);
-
-! fp = fopen (fname, "w");
- }
- if (fp == NULL)
---- 465,469 ----
- free (repname);
-
-! fp = CVS_FOPEN (fname, "w");
- }
- if (fp == NULL)
-diff -r -C 2 -P base/cvs-1.6.5/src/filesubr.c cvs-1.6.5/src/filesubr.c
-*** base/cvs-1.6.5/src/filesubr.c Tue Jan 2 06:20:27 1996
---- cvs-1.6.5/src/filesubr.c Tue Jan 9 05:48:57 1996
-***************
-*** 61,69 ****
- return;
-
-! if ((fdin = open (from, O_RDONLY)) < 0)
- error (1, errno, "cannot open %s for copying", from);
- if (fstat (fdin, &sb) < 0)
- error (1, errno, "cannot fstat %s", from);
-! if ((fdout = creat (to, (int) sb.st_mode & 07777)) < 0)
- error (1, errno, "cannot create %s for copying", to);
- if (sb.st_size > 0)
---- 61,69 ----
- return;
-
-! if ((fdin = CVS_OPEN (from, O_RDONLY)) < 0)
- error (1, errno, "cannot open %s for copying", from);
- if (fstat (fdin, &sb) < 0)
- error (1, errno, "cannot fstat %s", from);
-! if ((fdout = CVS_CREAT (to, (int) sb.st_mode & 07777)) < 0)
- error (1, errno, "cannot create %s for copying", to);
- if (sb.st_size > 0)
-***************
-*** 122,126 ****
- struct stat sb;
-
-! if (stat (file, &sb) < 0)
- return (0);
- return (S_ISDIR (sb.st_mode));
---- 122,126 ----
- struct stat sb;
-
-! if (CVS_STAT (file, &sb) < 0)
- return (0);
- return (S_ISDIR (sb.st_mode));
-***************
-*** 192,196 ****
- int uid;
-
-! if (stat(file, &sb) == -1)
- return 0;
- if (mode == F_OK)
---- 192,196 ----
- int uid;
-
-! if (CVS_STAT(file, &sb) == -1)
- return 0;
- if (mode == F_OK)
-***************
-*** 232,236 ****
- return (sb.st_mode & omask) == omask;
- #else
-! return access(file, mode) == 0;
- #endif
- }
---- 232,236 ----
- return (sb.st_mode & omask) == omask;
- #else
-! return CVS_ACCESS (file, mode) == 0;
- #endif
- }
-***************
-*** 246,250 ****
- FILE *fp;
-
-! if ((fp = fopen (name, mode)) == NULL)
- error (1, errno, "cannot open %s", name);
- return (fp);
---- 246,250 ----
- FILE *fp;
-
-! if ((fp = CVS_FOPEN (name, mode)) == NULL)
- error (1, errno, "cannot open %s", name);
- return (fp);
-***************
-*** 260,266 ****
- struct stat sb;
-
-! if (stat (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
- error (0, 0, "%s already exists but is not a directory", name);
-! if (!noexec && mkdir (name, 0777) < 0)
- error (1, errno, "cannot make directory %s", name);
- }
---- 260,266 ----
- struct stat sb;
-
-! if (CVS_STAT (name, &sb) == 0 && (!S_ISDIR (sb.st_mode)))
- error (0, 0, "%s already exists but is not a directory", name);
-! if (!noexec && CVS_MKDIR (name, 0777) < 0)
- error (1, errno, "cannot make directory %s", name);
- }
-***************
-*** 279,283 ****
- return;
-
-! if (mkdir (name, 0777) == 0 || errno == EEXIST)
- return;
- if (! existence_error (errno))
---- 279,283 ----
- return;
-
-! if (CVS_MKDIR (name, 0777) == 0 || errno == EEXIST)
- return;
- if (! existence_error (errno))
-***************
-*** 293,297 ****
- if (*cp == '\0')
- return;
-! (void) mkdir (name, 0777);
- }
-
---- 293,297 ----
- if (*cp == '\0')
- return;
-! (void) CVS_MKDIR (name, 0777);
- }
-
-***************
-*** 308,312 ****
- mode_t mode, oumask;
-
-! if (stat (fname, &sb) < 0)
- {
- if (!noexec)
---- 308,312 ----
- mode_t mode, oumask;
-
-! if (CVS_STAT (fname, &sb) < 0)
- {
- if (!noexec)
-***************
-*** 360,364 ****
- return;
-
-! if (rename (from, to) < 0)
- error (1, errno, "cannot rename file %s to %s", from, to);
- }
---- 360,364 ----
- return;
-
-! if (CVS_RENAME (from, to) < 0)
- error (1, errno, "cannot rename file %s to %s", from, to);
- }
-***************
-*** 384,388 ****
---- 384,392 ----
- return (0);
-
-+ #ifdef macintosh
-+ return (symlink (from, to));
-+ #else
- return (link (from, to));
-+ #endif
- }
-
-***************
-*** 404,408 ****
- return (0);
-
-! return (unlink (f));
- }
-
---- 408,412 ----
- return (0);
-
-! return (CVS_UNLINK (f));
- }
-
-***************
-*** 426,430 ****
- return (0);
-
-! if (unlink (f) != 0)
- {
- /* under NEXTSTEP errno is set to return EPERM if
---- 430,434 ----
- return (0);
-
-! if (CVS_UNLINK (f) != 0)
- {
- /* under NEXTSTEP errno is set to return EPERM if
-***************
-*** 461,465 ****
- if ( rmdir (path) != 0 && errno == ENOTEMPTY )
- {
-! if ((dirp = opendir (path)) == NULL)
- /* If unable to open the directory return
- * an error
---- 465,469 ----
- if ( rmdir (path) != 0 && errno == ENOTEMPTY )
- {
-! if ((dirp = CVS_OPENDIR (path)) == NULL)
- /* If unable to open the directory return
- * an error
-***************
-*** 475,479 ****
- sprintf (buf, "%s/%s", path, dp->d_name);
-
-! if (unlink (buf) != 0 )
- {
- if (errno == EISDIR || errno == EPERM)
---- 479,483 ----
- sprintf (buf, "%s/%s", path, dp->d_name);
-
-! if (CVS_UNLINK (buf) != 0 )
- {
- if (errno == EISDIR || errno == EPERM)
-***************
-*** 550,556 ****
- int ret;
-
-! if ((fd1 = open (file1, O_RDONLY)) < 0)
- error (1, errno, "cannot open file %s for comparing", file1);
-! if ((fd2 = open (file2, O_RDONLY)) < 0)
- error (1, errno, "cannot open file %s for comparing", file2);
- if (fstat (fd1, &sb1) < 0)
---- 554,560 ----
- int ret;
-
-! if ((fd1 = CVS_OPEN (file1, O_RDONLY)) < 0)
- error (1, errno, "cannot open file %s for comparing", file1);
-! if ((fd2 = CVS_OPEN (file2, O_RDONLY)) < 0)
- error (1, errno, "cannot open file %s for comparing", file2);
- if (fstat (fd1, &sb1) < 0)
-diff -r -C 2 -P base/cvs-1.6.5/src/find_names.c cvs-1.6.5/src/find_names.c
-*** base/cvs-1.6.5/src/find_names.c Sat Dec 16 06:20:30 1995
---- cvs-1.6.5/src/find_names.c Tue Jan 9 05:33:07 1996
-***************
-*** 129,133 ****
- /* look only for CVS controlled sub-directories */
- if (find_dirs (".", dirlist, 1) != 0)
-! error (1, errno, "cannot open current directory");
- }
-
---- 129,133 ----
- /* look only for CVS controlled sub-directories */
- if (find_dirs (".", dirlist, 1) != 0)
-! error (1, errno, "cannot open current directory\n");
- }
-
-***************
-*** 171,175 ****
-
- /* set up to read the dir */
-! if ((dirp = opendir (dir)) == NULL)
- return (1);
-
---- 171,175 ----
-
- /* set up to read the dir */
-! if ((dirp = CVS_OPENDIR (dir)) == NULL)
- return (1);
-
-***************
-*** 211,217 ****
-
- /* set up to read the dir */
-! if ((dirp = opendir (dir)) == NULL)
- return (1);
--
- /* read the dir, grabbing sub-dirs */
- while ((dp = readdir (dirp)) != NULL)
---- 211,216 ----
-
- /* set up to read the dir */
-! if ((dirp = CVS_OPENDIR (dir)) == NULL)
- return (1);
- /* read the dir, grabbing sub-dirs */
- while ((dp = readdir (dirp)) != NULL)
-diff -r -C 2 -P base/cvs-1.6.5/src/history.c cvs-1.6.5/src/history.c
-*** base/cvs-1.6.5/src/history.c Thu Jan 4 06:20:28 1996
---- cvs-1.6.5/src/history.c Tue Jan 9 05:33:07 1996
-***************
-*** 702,706 ****
- if (noexec)
- return;
-! if ((fd = open (fname, O_WRONLY | O_APPEND | O_CREAT, 0666)) < 0)
- error (1, errno, "cannot open history file: %s", fname);
-
---- 702,706 ----
- if (noexec)
- return;
-! if ((fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT, 0666)) < 0)
- error (1, errno, "cannot open history file: %s", fname);
-
-***************
-*** 729,737 ****
- if (!getwd (workdir))
- error (1, errno, "can't getwd in history");
-! if (chdir (pw->pw_dir) < 0)
- error (1, errno, "can't chdir(%s)", pw->pw_dir);
- if (!getwd (homedir))
- error (1, errno, "can't getwd in %s", pw->pw_dir);
-! (void) chdir (workdir);
-
- i = strlen (homedir);
---- 729,737 ----
- if (!getwd (workdir))
- error (1, errno, "can't getwd in history");
-! if (CVS_CHDIR (pw->pw_dir) < 0)
- error (1, errno, "can't chdir(%s)", pw->pw_dir);
- if (!getwd (homedir))
- error (1, errno, "can't getwd in %s", pw->pw_dir);
-! (void) CVS_CHDIR (workdir);
-
- i = strlen (homedir);
-***************
-*** 1001,1005 ****
- struct stat st_buf;
-
-! if ((fd = open (fname, O_RDONLY)) < 0)
- error (1, errno, "cannot open history file: %s", fname);
-
---- 1001,1005 ----
- struct stat st_buf;
-
-! if ((fd = CVS_OPEN (fname, O_RDONLY)) < 0)
- error (1, errno, "cannot open history file: %s", fname);
-
-diff -r -C 2 -P base/cvs-1.6.5/src/ignore.c cvs-1.6.5/src/ignore.c
-*** base/cvs-1.6.5/src/ignore.c Thu Jan 4 06:20:29 1996
---- cvs-1.6.5/src/ignore.c Tue Jan 9 05:33:07 1996
-***************
-*** 132,136 ****
-
- /* load the file */
-! fp = fopen (file, "r");
- if (fp == NULL)
- {
---- 132,136 ----
-
- /* load the file */
-! fp = CVS_FOPEN (file, "r");
- if (fp == NULL)
- {
-***************
-*** 317,321 ****
- xdir = update_dir;
-
-! dirp = opendir (".");
- if (dirp == NULL)
- return;
---- 317,321 ----
- xdir = update_dir;
-
-! dirp = CVS_OPENDIR (".");
- if (dirp == NULL)
- return;
-diff -r -C 2 -P base/cvs-1.6.5/src/import.c cvs-1.6.5/src/import.c
-*** base/cvs-1.6.5/src/import.c Thu Jan 4 06:20:29 1996
---- cvs-1.6.5/src/import.c Tue Jan 9 05:33:08 1996
-***************
-*** 250,256 ****
-
- /* Create the logfile that will be logged upon completion */
-! if ((logfp = fopen (tmpnam (tmpfile), "w+")) == NULL)
- error (1, errno, "cannot create temporary file `%s'", tmpfile);
-! (void) unlink (tmpfile); /* to be sure it goes away */
- (void) fprintf (logfp, "\nVendor Tag:\t%s\n", argv[1]);
- (void) fprintf (logfp, "Release Tags:\t");
---- 250,256 ----
-
- /* Create the logfile that will be logged upon completion */
-! if ((logfp = CVS_FOPEN (tmpnam (tmpfile), "w+")) == NULL)
- error (1, errno, "cannot create temporary file `%s'", tmpfile);
-! (void) CVS_UNLINK (tmpfile); /* to be sure it goes away */
- (void) fprintf (logfp, "\nVendor Tag:\t%s\n", argv[1]);
- (void) fprintf (logfp, "Release Tags:\t");
-***************
-*** 302,306 ****
- /* Make sure the temporary file goes away, even on systems that don't let
- you delete a file that's in use. */
-! unlink (tmpfile);
-
- if (message)
---- 302,306 ----
- /* Make sure the temporary file goes away, even on systems that don't let
- you delete a file that's in use. */
-! CVS_UNLINK (tmpfile);
-
- if (message)
-***************
-*** 329,333 ****
- wrap_add_file (CVSDOTWRAPPER, 1);
-
-! if ((dirp = opendir (".")) == NULL)
- {
- err++;
---- 329,333 ----
- wrap_add_file (CVSDOTWRAPPER, 1);
-
-! if ((dirp = CVS_OPENDIR (".")) == NULL)
- {
- err++;
-***************
-*** 867,871 ****
- tocvsPath = wrap_tocvs_process_file (user);
- userfile = (tocvsPath == NULL ? user : tocvsPath);
-! fpuser = fopen (userfile, "r");
- if (fpuser == NULL) {
- /* not fatal, continue import */
---- 867,871 ----
- tocvsPath = wrap_tocvs_process_file (user);
- userfile = (tocvsPath == NULL ? user : tocvsPath);
-! fpuser = CVS_FOPEN (userfile, "r");
- if (fpuser == NULL) {
- /* not fatal, continue import */
-***************
-*** 874,878 ****
- goto read_error;
- }
-! fprcs = fopen (rcs, "w+");
- if (fprcs == NULL) {
- ierrno = errno;
---- 874,878 ----
- goto read_error;
- }
-! fprcs = CVS_FOPEN (rcs, "w+");
- if (fprcs == NULL) {
- ierrno = errno;
-***************
-*** 1036,1040 ****
- if (ierrno == ENOSPC)
- {
-! (void) unlink (rcs);
- fperror (logfp, 0, 0, "ERROR: out of space - aborting");
- error (1, 0, "ERROR: out of space - aborting");
---- 1036,1040 ----
- if (ierrno == ENOSPC)
- {
-! (void) CVS_UNLINK (rcs);
- fperror (logfp, 0, 0, "ERROR: out of space - aborting");
- error (1, 0, "ERROR: out of space - aborting");
-***************
-*** 1149,1153 ****
- #endif
-
-! if (chdir (dir) < 0)
- {
- ierrno = errno;
---- 1149,1153 ----
- #endif
-
-! if (CVS_CHDIR (dir) < 0)
- {
- ierrno = errno;
-diff -r -C 2 -P base/cvs-1.6.5/src/lock.c cvs-1.6.5/src/lock.c
-*** base/cvs-1.6.5/src/lock.c Mon Dec 18 06:20:26 1995
---- cvs-1.6.5/src/lock.c Tue Jan 9 05:33:08 1996
-***************
-*** 84,88 ****
- {
- (void) sprintf (tmp, "%s/%s", repository, readlock);
-! if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- }
---- 84,88 ----
- {
- (void) sprintf (tmp, "%s/%s", repository, readlock);
-! if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- }
-***************
-*** 91,95 ****
- {
- (void) sprintf (tmp, "%s/%s", repository, writelock);
-! if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- }
---- 91,95 ----
- {
- (void) sprintf (tmp, "%s/%s", repository, writelock);
-! if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- }
-***************
-*** 133,137 ****
- /* Check if the uidlock is in the lock directory */
- sprintf(uidlock, "%s/uidlock%d", lockdir, geteuid() );
-! if( stat(uidlock, &sb) != -1)
- return 1; /* The file exists, therefore we own the lock */
- else
---- 133,137 ----
- /* Check if the uidlock is in the lock directory */
- sprintf(uidlock, "%s/uidlock%d", lockdir, geteuid() );
-! if( CVS_STAT (uidlock, &sb) != -1)
- return 1; /* The file exists, therefore we own the lock */
- else
-***************
-*** 140,144 ****
- */
- #else
-! if (stat (lockdir, &sb) != -1 && sb.st_uid == geteuid ())
- return 1;
- else
---- 140,144 ----
- */
- #else
-! if (CVS_STAT (lockdir, &sb) != -1 && sb.st_uid == geteuid ())
- return 1;
- else
-***************
-*** 190,203 ****
- #endif
- getpid());
-! if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create read lock in repository `%s'",
- xrepository);
- readlock[0] = '\0';
-! if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- return (1);
- }
-! if (unlink (tmp) < 0)
- error (0, errno, "failed to remove lock %s", tmp);
- #endif
---- 190,203 ----
- #endif
- getpid());
-! if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create read lock in repository `%s'",
- xrepository);
- readlock[0] = '\0';
-! if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- return (1);
- }
-! if (CVS_UNLINK (tmp) < 0)
- error (0, errno, "failed to remove lock %s", tmp);
- #endif
-***************
-*** 214,218 ****
- /* write a read-lock */
- (void) sprintf (tmp, "%s/%s", xrepository, readlock);
-! if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create read lock in repository `%s'",
---- 214,218 ----
- /* write a read-lock */
- (void) sprintf (tmp, "%s/%s", xrepository, readlock);
-! if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create read lock in repository `%s'",
-***************
-*** 328,340 ****
- #endif
- getpid ());
-! if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create write lock in repository `%s'",
- repository);
-! if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- return (L_ERROR);
- }
-! if (unlink (tmp) < 0)
- error (0, errno, "failed to remove lock %s", tmp);
- #endif
---- 328,340 ----
- #endif
- getpid ());
-! if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- error (0, errno, "cannot create write lock in repository `%s'",
- repository);
-! if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
- return (L_ERROR);
- }
-! if (CVS_UNLINK (tmp) < 0)
- error (0, errno, "failed to remove lock %s", tmp);
- #endif
-***************
-*** 359,367 ****
- /* write the write-lock file */
- (void) sprintf (tmp, "%s/%s", repository, writelock);
-! if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- int xerrno = errno;
-
-! if (unlink (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
-
---- 359,367 ----
- /* write the write-lock file */
- (void) sprintf (tmp, "%s/%s", repository, writelock);
-! if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF)
- {
- int xerrno = errno;
-
-! if (CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
- error (0, errno, "failed to remove lock %s", tmp);
-
-***************
-*** 402,406 ****
- #endif
-
-! if ((dirp = opendir (repository)) == NULL)
- error (1, 0, "cannot open directory %s", repository);
-
---- 402,406 ----
- #endif
-
-! if ((dirp = CVS_OPENDIR (repository)) == NULL)
- error (1, 0, "cannot open directory %s", repository);
-
-***************
-*** 417,421 ****
- line = xmalloc (strlen (repository) + strlen (dp->d_name) + 5);
- (void) sprintf (line, "%s/%s", repository, dp->d_name);
-! if (stat (line, &sb) != -1)
- {
- #ifdef CVS_FUDGELOCKS
---- 417,421 ----
- line = xmalloc (strlen (repository) + strlen (dp->d_name) + 5);
- (void) sprintf (line, "%s/%s", repository, dp->d_name);
-! if (CVS_STAT (line, &sb) != -1)
- {
- #ifdef CVS_FUDGELOCKS
-***************
-*** 425,429 ****
- * successful, re-open the directory and try again.
- */
-! if (now >= (sb.st_ctime + CVSLCKAGE) && unlink (line) != -1)
- {
- (void) closedir (dirp);
---- 425,429 ----
- * successful, re-open the directory and try again.
- */
-! if (now >= (sb.st_ctime + CVSLCKAGE) && CVS_UNLINK (line) != -1)
- {
- (void) closedir (dirp);
-***************
-*** 503,507 ****
-
- sprintf(uidlock, "%s/uidlock%d", masterlock, geteuid() );
-! if ((fp = fopen(uidlock, "w+")) == NULL)
- {
- /* We failed to create the uidlock,
---- 503,507 ----
-
- sprintf(uidlock, "%s/uidlock%d", masterlock, geteuid() );
-! if ((fp = CVS_FOPEN (uidlock, "w+")) == NULL)
- {
- /* We failed to create the uidlock,
-***************
-*** 539,543 ****
- * someone probably just removed it (thus releasing the lock)
- */
-! if (stat (masterlock, &sb) < 0)
- {
- if (existence_error (errno))
---- 539,543 ----
- * someone probably just removed it (thus releasing the lock)
- */
-! if (CVS_STAT (masterlock, &sb) < 0)
- {
- if (existence_error (errno))
-diff -r -C 2 -P base/cvs-1.6.5/src/login.c cvs-1.6.5/src/login.c
-*** base/cvs-1.6.5/src/login.c Sun Dec 24 06:20:24 1995
---- cvs-1.6.5/src/login.c Tue Jan 9 05:33:08 1996
-***************
-*** 192,196 ****
- inefficient, but we're not talking about a gig of data here. */
-
-! fp = fopen (passfile, "r");
- if (fp != NULL)
- {
---- 192,196 ----
- inefficient, but we're not talking about a gig of data here. */
-
-! fp = CVS_FOPEN (passfile, "r");
- if (fp != NULL)
- {
-***************
-*** 232,236 ****
-
- tmp_name = tmpnam (NULL);
-! if ((tmp_fp = fopen (tmp_name, "w")) == NULL)
- {
- error (1, errno, "unable to open temp file %s", tmp_name);
---- 232,236 ----
-
- tmp_name = tmpnam (NULL);
-! if ((tmp_fp = CVS_FOPEN (tmp_name, "w")) == NULL)
- {
- error (1, errno, "unable to open temp file %s", tmp_name);
-***************
-*** 239,243 ****
- chmod (tmp_name, 0600);
-
-! fp = fopen (passfile, "r");
- if (fp == NULL)
- {
---- 239,243 ----
- chmod (tmp_name, 0600);
-
-! fp = CVS_FOPEN (passfile, "r");
- if (fp == NULL)
- {
-***************
-*** 268,272 ****
- else
- {
-! if ((fp = fopen (passfile, "a")) == NULL)
- {
- error (1, errno, "could not open %s", passfile);
---- 268,272 ----
- else
- {
-! if ((fp = CVS_FOPEN (passfile, "a")) == NULL)
- {
- error (1, errno, "could not open %s", passfile);
-***************
-*** 327,331 ****
- /* Else get it from the file. */
- passfile = construct_cvspass_filename ();
-! fp = fopen (passfile, "r");
- if (fp == NULL)
- {
---- 327,331 ----
- /* Else get it from the file. */
- passfile = construct_cvspass_filename ();
-! fp = CVS_FOPEN (passfile, "r");
- if (fp == NULL)
- {
-diff -r -C 2 -P base/cvs-1.6.5/src/logmsg.c cvs-1.6.5/src/logmsg.c
-*** base/cvs-1.6.5/src/logmsg.c Mon Dec 25 06:20:18 1995
---- cvs-1.6.5/src/logmsg.c Tue Jan 9 05:33:08 1996
-***************
-*** 145,149 ****
- (void) tmpnam (fname);
- again:
-! if ((fp = fopen (fname, "w+")) == NULL)
- error (1, 0, "cannot create temporary file %s", fname);
-
---- 145,149 ----
- (void) tmpnam (fname);
- again:
-! if ((fp = CVS_FOPEN (fname, "w+")) == NULL)
- error (1, 0, "cannot create temporary file %s", fname);
-
-***************
-*** 180,184 ****
- if (fclose (fp) == EOF)
- error (1, errno, "%s", fname);
-! if (stat (fname, &pre_stbuf) == -1)
- pre_stbuf.st_mtime = 0;
-
---- 180,184 ----
- if (fclose (fp) == EOF)
- error (1, errno, "%s", fname);
-! if (CVS_STAT (fname, &pre_stbuf) == -1)
- pre_stbuf.st_mtime = 0;
-
-***************
-*** 205,209 ****
- free (*messagep);
-
-! if (stat (fname, &post_stbuf) != 0)
- error (1, errno, "cannot find size of temp file %s", fname);
-
---- 205,209 ----
- free (*messagep);
-
-! if (CVS_STAT (fname, &post_stbuf) != 0)
- error (1, errno, "cannot find size of temp file %s", fname);
-
-***************
-*** 293,297 ****
- last_template = xstrdup (template);
-
-! if ((tfp = fopen (template, "r")) != NULL)
- {
- char *line = NULL;
---- 293,297 ----
- last_template = xstrdup (template);
-
-! if ((tfp = CVS_FOPEN (template, "r")) != NULL)
- {
- char *line = NULL;
-diff -r -C 2 -P base/cvs-1.6.5/src/main.c cvs-1.6.5/src/main.c
-*** base/cvs-1.6.5/src/main.c Sat Dec 16 06:20:32 1995
---- cvs-1.6.5/src/main.c Tue Jan 9 05:33:08 1996
-***************
-*** 37,40 ****
---- 37,44 ----
- #include "patchlevel.h"
-
-+ #ifdef macintosh
-+ #include <sioux.h>
-+ #endif
-+
- #if HAVE_KERBEROS
- #include <sys/socket.h>
-***************
-*** 269,272 ****
---- 273,285 ----
- don't use it. */
- int option_index = 0;
-+
-+ #ifdef macintosh
-+ GUSIDefaultSetup();
-+ argc = ccommand(&argv);
-+
-+ SIOUXSettings.showstatusline = TRUE;
-+ SIOUXSettings.asktosaveonclose = FALSE;
-+
-+ #endif
-
- error_set_cleanup (error_cleanup);
-diff -r -C 2 -P base/cvs-1.6.5/src/modules.c cvs-1.6.5/src/modules.c
-*** base/cvs-1.6.5/src/modules.c Thu Jan 4 06:20:30 1996
---- cvs-1.6.5/src/modules.c Tue Jan 9 05:33:08 1996
-***************
-*** 338,342 ****
- instead of just at the bottom */
- make_directories (dir);
-! if (chdir (dir) < 0)
- {
- error (0, errno, "cannot chdir to %s", dir);
---- 338,342 ----
- instead of just at the bottom */
- make_directories (dir);
-! if (CVS_CHDIR (dir) < 0)
- {
- error (0, errno, "cannot chdir to %s", dir);
-***************
-*** 643,647 ****
- static int s_count = 0; /* Number of elements used */
-
-! static int Status; /* Nonzero if the user is
- interested in status
- information as well as
---- 643,647 ----
- static int s_count = 0; /* Number of elements used */
-
-! static int capsstatus; /* Nonzero if the user is
- interested in status
- information as well as
-***************
-*** 663,667 ****
- const struct sortrec *right = (const struct sortrec *) r;
-
-! if (Status)
- {
- /* If Sort by status field, compare them. */
---- 663,667 ----
- const struct sortrec *right = (const struct sortrec *) r;
-
-! if (capsstatus)
- {
- /* If Sort by status field, compare them. */
-***************
-*** 682,686 ****
- struct sortrec *s_rec;
-
-! if (Status && *d == '-' && *(d + 1) == 'a')
- return; /* We want "cvs co -s" and it is an alias! */
-
---- 682,686 ----
- struct sortrec *s_rec;
-
-! if (capsstatus && *d == '-' && *(d + 1) == 'a')
- return; /* We want "cvs co -s" and it is an alias! */
-
-***************
-*** 716,720 ****
-
- /* Look for the "-s statusvalue" text */
-! if (Status)
- {
- s_rec->status = def_status;
---- 716,720 ----
-
- /* Look for the "-s statusvalue" text */
-! if (capsstatus)
- {
- s_rec->status = def_status;
-***************
-*** 779,788 ****
- struct winsize ws;
-
-! (void) ioctl (0, TIOCGWINSZ, &ws);
- cols = ws.ws_col;
- #endif
- #endif
-
-! Status = status;
-
- /* Read the whole modules file into allocated records */
---- 779,792 ----
- struct winsize ws;
-
-! #ifdef __MWERKS__
-! (void) ioctl (0, TIOCGWINSZ, (long *) &ws);
-! #else
-! (void) ioctl (0, TIOCGWINSZ, &ws);
-! #endif
- cols = ws.ws_col;
- #endif
- #endif
-
-! capsstatus = status;
-
- /* Read the whole modules file into allocated records */
-diff -r -C 2 -P base/cvs-1.6.5/src/myndbm.c cvs-1.6.5/src/myndbm.c
-*** base/cvs-1.6.5/src/myndbm.c Wed Jan 3 06:20:24 1996
---- cvs-1.6.5/src/myndbm.c Tue Jan 9 05:33:08 1996
-***************
-*** 37,41 ****
- DBM *db;
-
-! fp = fopen (file, "r");
- if (fp == NULL && !(existence_error (errno) && (flags & O_CREAT)))
- return ((DBM *) 0);
---- 37,41 ----
- DBM *db;
-
-! fp = CVS_FOPEN (file, "r");
- if (fp == NULL && !(existence_error (errno) && (flags & O_CREAT)))
- return ((DBM *) 0);
-***************
-*** 77,81 ****
- {
- FILE *fp;
-! fp = fopen (db->name, "w");
- if (fp == NULL)
- error (1, errno, "cannot write %s", db->name);
---- 77,81 ----
- {
- FILE *fp;
-! fp = CVS_FOPEN (db->name, "w");
- if (fp == NULL)
- error (1, errno, "cannot write %s", db->name);
-diff -r -C 2 -P base/cvs-1.6.5/src/no_diff.c cvs-1.6.5/src/no_diff.c
-*** base/cvs-1.6.5/src/no_diff.c Fri Sep 8 07:20:28 1995
---- cvs-1.6.5/src/no_diff.c Tue Jan 9 05:33:08 1996
-***************
-*** 98,102 ****
- * has been set to 1. */
- if (trace)
-! (void) fprintf (stderr, "%c-> unlink (%s)\n",
- #ifdef SERVER_SUPPORT
- (server_active) ? 'S' : ' ',
---- 98,102 ----
- * has been set to 1. */
- if (trace)
-! (void) fprintf (stderr, "%c-> CVS_UNLINK (%s)\n",
- #ifdef SERVER_SUPPORT
- (server_active) ? 'S' : ' ',
-***************
-*** 105,109 ****
- #endif
- tocvsPath);
-! if (unlink (tocvsPath) < 0)
- error (0, errno, "could not remove %s", tocvsPath);
- }
---- 105,109 ----
- #endif
- tocvsPath);
-! if (CVS_UNLINK (tocvsPath) < 0)
- error (0, errno, "could not remove %s", tocvsPath);
- }
-***************
-*** 127,133 ****
- (server_active) ? 'S' : ' ', tmp);
- #else
-! (void) fprintf (stderr, "-> unlink (%s)\n", tmp);
- #endif
-! if (unlink (tmp) < 0)
- error (0, errno, "could not remove %s", tmp);
- free (options);
---- 127,133 ----
- (server_active) ? 'S' : ' ', tmp);
- #else
-! (void) fprintf (stderr, "-> CVS_UNLINK (%s)\n", tmp);
- #endif
-! if (CVS_UNLINK (tmp) < 0)
- error (0, errno, "could not remove %s", tmp);
- free (options);
-diff -r -C 2 -P base/cvs-1.6.5/src/parseinfo.c cvs-1.6.5/src/parseinfo.c
-*** base/cvs-1.6.5/src/parseinfo.c Tue Oct 17 07:20:14 1995
---- cvs-1.6.5/src/parseinfo.c Tue Jan 9 05:33:08 1996
-***************
-*** 48,52 ****
- (void) sprintf (infopath, "%s/%s/%s", CVSroot,
- CVSROOTADM, infofile);
-! if ((fp_info = fopen (infopath, "r")) == NULL)
- return (0); /* no file -> nothing special done */
-
---- 48,52 ----
- (void) sprintf (infopath, "%s/%s/%s", CVSroot,
- CVSROOTADM, infofile);
-! if ((fp_info = CVS_FOPEN (infopath, "r")) == NULL)
- return (0); /* no file -> nothing special done */
-
-diff -r -C 2 -P base/cvs-1.6.5/src/patch.c cvs-1.6.5/src/patch.c
-*** base/cvs-1.6.5/src/patch.c Thu Jan 4 06:20:30 1996
---- cvs-1.6.5/src/patch.c Tue Jan 9 05:33:08 1996
-***************
-*** 302,306 ****
-
- /* cd to the starting repository */
-! if (chdir (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
---- 302,306 ----
-
- /* cd to the starting repository */
-! if (CVS_CHDIR (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
-***************
-*** 428,436 ****
- return (0);
- }
-! if ((fp1 = fopen (tmpnam (tmpfile1), "w+")) != NULL)
- (void) fclose (fp1);
-! if ((fp2 = fopen (tmpnam (tmpfile2), "w+")) != NULL)
- (void) fclose (fp2);
-! if ((fp3 = fopen (tmpnam (tmpfile3), "w+")) != NULL)
- (void) fclose (fp3);
- if (fp1 == NULL || fp2 == NULL || fp3 == NULL)
---- 428,436 ----
- return (0);
- }
-! if ((fp1 = CVS_FOPEN (tmpnam (tmpfile1), "w+")) != NULL)
- (void) fclose (fp1);
-! if ((fp2 = CVS_FOPEN (tmpnam (tmpfile2), "w+")) != NULL)
- (void) fclose (fp2);
-! if ((fp3 = CVS_FOPEN (tmpnam (tmpfile3), "w+")) != NULL)
- (void) fclose (fp3);
- if (fp1 == NULL || fp2 == NULL || fp3 == NULL)
-diff -r -C 2 -P base/cvs-1.6.5/src/rcs.c cvs-1.6.5/src/rcs.c
-*** base/cvs-1.6.5/src/rcs.c Mon Dec 4 06:20:22 1995
---- cvs-1.6.5/src/rcs.c Tue Jan 9 05:33:08 1996
-***************
-*** 144,148 ****
-
- (void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT);
-! if ((fp = fopen (rcsfile, "r")) != NULL)
- {
- rcs = RCS_parsercsfile_i(fp, rcsfile);
---- 144,148 ----
-
- (void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT);
-! if ((fp = CVS_FOPEN (rcsfile, "r")) != NULL)
- {
- rcs = RCS_parsercsfile_i(fp, rcsfile);
-***************
-*** 166,170 ****
-
- (void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC, file, RCSEXT);
-! if ((fp = fopen (rcsfile, "r")) != NULL)
- {
- rcs = RCS_parsercsfile_i(fp, rcsfile);
---- 166,170 ----
-
- (void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC, file, RCSEXT);
-! if ((fp = CVS_FOPEN (rcsfile, "r")) != NULL)
- {
- rcs = RCS_parsercsfile_i(fp, rcsfile);
-***************
-*** 204,208 ****
-
- /* open the rcsfile */
-! if ((fp = fopen (rcsfile, "r")) == NULL)
- {
- error (0, errno, "Couldn't open rcs file `%s'", rcsfile);
---- 204,208 ----
-
- /* open the rcsfile */
-! if ((fp = CVS_FOPEN (rcsfile, "r")) == NULL)
- {
- error (0, errno, "Couldn't open rcs file `%s'", rcsfile);
-***************
-*** 308,312 ****
- #endif
-
-! fp = fopen(rcsfile, "r");
- if (fp == NULL)
- error (1, 0, "unable to reopen `%s'", rcsfile);
---- 308,312 ----
- #endif
-
-! fp = CVS_FOPEN (rcsfile, "r");
- if (fp == NULL)
- error (1, 0, "unable to reopen `%s'", rcsfile);
-diff -r -C 2 -P base/cvs-1.6.5/src/recurse.c cvs-1.6.5/src/recurse.c
-*** base/cvs-1.6.5/src/recurse.c Sat Dec 16 06:20:33 1995
---- cvs-1.6.5/src/recurse.c Tue Jan 9 05:33:08 1996
-***************
-*** 519,523 ****
-
- /* cd to the sub-directory */
-! if (chdir (dir) < 0)
- error (1, errno, "could not chdir to %s", dir);
-
---- 519,523 ----
-
- /* cd to the sub-directory */
-! if (CVS_CHDIR (dir) < 0)
- error (1, errno, "could not chdir to %s", dir);
-
-***************
-*** 631,635 ****
- if (save_cwd (&cwd))
- exit (1);
-! if (chdir (p->key) < 0)
- error (1, errno, "could not chdir to %s", p->key);
-
---- 631,635 ----
- if (save_cwd (&cwd))
- exit (1);
-! if (CVS_CHDIR (p->key) < 0)
- error (1, errno, "could not chdir to %s", p->key);
-
-diff -r -C 2 -P base/cvs-1.6.5/src/release.c cvs-1.6.5/src/release.c
-*** base/cvs-1.6.5/src/release.c Tue Jan 9 06:20:21 1996
---- cvs-1.6.5/src/release.c Tue Jan 9 05:33:08 1996
-***************
-*** 143,147 ****
- if (isdir (thisarg))
- {
-! if (chdir (thisarg) < 0)
- {
- if (!really_quiet)
---- 143,147 ----
- if (isdir (thisarg))
- {
-! if (CVS_CHDIR (thisarg) < 0)
- {
- if (!really_quiet)
-***************
-*** 273,280 ****
- ino_t ino;
-
-! (void) stat (".", &st);
- ino = st.st_ino;
-! (void) chdir ("..");
-! (void) stat (dir, &st);
- if (ino != st.st_ino)
- {
---- 273,280 ----
- ino_t ino;
-
-! (void) CVS_STAT (".", &st);
- ino = st.st_ino;
-! (void) CVS_CHDIR ("..");
-! (void) CVS_STAT (dir, &st);
- if (ino != st.st_ino)
- {
-diff -r -C 2 -P base/cvs-1.6.5/src/remove.c cvs-1.6.5/src/remove.c
-*** base/cvs-1.6.5/src/remove.c Thu Jan 4 06:20:31 1996
---- cvs-1.6.5/src/remove.c Tue Jan 9 05:33:08 1996
-***************
-*** 128,132 ****
- if (!noexec)
- {
-! if (unlink (file) < 0 && ! existence_error (errno))
- {
- if (update_dir[0] == '\0')
---- 128,132 ----
- if (!noexec)
- {
-! if (CVS_UNLINK (file) < 0 && ! existence_error (errno))
- {
- if (update_dir[0] == '\0')
-diff -r -C 2 -P base/cvs-1.6.5/src/root.c cvs-1.6.5/src/root.c
-*** base/cvs-1.6.5/src/root.c Tue Dec 12 06:20:28 1995
---- cvs-1.6.5/src/root.c Tue Jan 9 05:33:08 1996
-***************
-*** 136,142 ****
- int ret;
-
-! if (stat (dir1, &sb1) < 0)
- return (0);
-! if (stat (dir2, &sb2) < 0)
- return (0);
-
---- 136,142 ----
- int ret;
-
-! if (CVS_STAT (dir1, &sb1) < 0)
- return (0);
-! if (CVS_STAT (dir2, &sb2) < 0)
- return (0);
-
-diff -r -C 2 -P base/cvs-1.6.5/src/rtag.c cvs-1.6.5/src/rtag.c
-*** base/cvs-1.6.5/src/rtag.c Thu Jan 4 06:20:31 1996
---- cvs-1.6.5/src/rtag.c Tue Jan 9 05:33:08 1996
-***************
-*** 279,283 ****
-
- /* chdir to the starting directory */
-! if (chdir (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
---- 279,283 ----
-
- /* chdir to the starting directory */
-! if (CVS_CHDIR (repository) < 0)
- {
- error (0, errno, "cannot chdir to %s", repository);
-diff -r -C 2 -P base/cvs-1.6.5/src/run.c cvs-1.6.5/src/run.c
-*** base/cvs-1.6.5/src/run.c Fri Dec 15 06:20:21 1995
---- cvs-1.6.5/src/run.c Tue Jan 9 05:33:08 1996
-***************
-*** 216,220 ****
- mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
-
-! if (stin && (shin = open (stin, O_RDONLY)) == -1)
- {
- rerrno = errno;
---- 216,220 ----
- mode_err |= ((flags & RUN_STDERR_APPEND) ? O_APPEND : O_TRUNC);
-
-! if (stin && (shin = CVS_OPEN (stin, O_RDONLY)) == -1)
- {
- rerrno = errno;
-***************
-*** 223,227 ****
- goto out0;
- }
-! if (stout && (shout = open (stout, mode_out, 0666)) == -1)
- {
- rerrno = errno;
---- 223,227 ----
- goto out0;
- }
-! if (stout && (shout = CVS_OPEN (stout, mode_out, 0666)) == -1)
- {
- rerrno = errno;
-***************
-*** 232,236 ****
- if (sterr && (flags & RUN_COMBINED) == 0)
- {
-! if ((sherr = open (sterr, mode_err, 0666)) == -1)
- {
- rerrno = errno;
---- 232,236 ----
- if (sterr && (flags & RUN_COMBINED) == 0)
- {
-! if ((sherr = CVS_OPEN (sterr, mode_err, 0666)) == -1)
- {
- rerrno = errno;
-diff -r -C 2 -P base/cvs-1.6.5/src/server.c cvs-1.6.5/src/server.c
-*** base/cvs-1.6.5/src/server.c Thu Jan 4 06:20:33 1996
---- cvs-1.6.5/src/server.c Tue Jan 9 05:33:08 1996
-***************
-*** 392,396 ****
- return;
- }
-! if (chdir (dirname) < 0)
- {
- pending_error = errno;
---- 392,396 ----
- return;
- }
-! if (CVS_CHDIR (dirname) < 0)
- {
- pending_error = errno;
-***************
-*** 411,415 ****
- return;
- }
-! f = fopen (CVSADM_REP, "w");
- if (f == NULL)
- {
---- 411,415 ----
- return;
- }
-! f = CVS_FOPEN (CVSADM_REP, "w");
- if (f == NULL)
- {
-***************
-*** 428,432 ****
- return;
- }
-! f = fopen (CVSADM_ENT, "w+");
- if (f == NULL)
- {
---- 428,432 ----
- return;
- }
-! f = CVS_FOPEN (CVSADM_ENT, "w+");
- if (f == NULL)
- {
-***************
-*** 493,497 ****
- {
- FILE *f;
-! f = fopen (CVSADM_ENTSTAT, "w+");
- if (f == NULL)
- {
---- 493,497 ----
- {
- FILE *f;
-! f = CVS_FOPEN (CVSADM_ENTSTAT, "w+");
- if (f == NULL)
- {
-***************
-*** 515,519 ****
- {
- FILE *f;
-! f = fopen (CVSADM_TAG, "w+");
- if (f == NULL)
- {
---- 515,519 ----
- {
- FILE *f;
-! f = CVS_FOPEN (CVSADM_TAG, "w+");
- if (f == NULL)
- {
-***************
-*** 626,630 ****
-
- /* Write the file. */
-! fd = open (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
- if (fd < 0)
- {
---- 626,630 ----
-
- /* Write the file. */
-! fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
- if (fd < 0)
- {
-***************
-*** 798,802 ****
- {
- struct utimbuf ut;
-! int fd = open (arg, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (fd < 0 || close (fd) < 0)
- {
---- 798,802 ----
- {
- struct utimbuf ut;
-! int fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (fd < 0 || close (fd) < 0)
- {
-***************
-*** 914,918 ****
- if (!error_pending ())
- {
-! f = fopen (CVSADM_ENT, "w");
- if (f == NULL)
- {
---- 914,918 ----
- if (!error_pending ())
- {
-! f = CVS_FOPEN (CVSADM_ENT, "w");
- if (f == NULL)
- {
-***************
-*** 1091,1095 ****
- while (notify_list != NULL)
- {
-! if (chdir (notify_list->dir) < 0)
- {
- error (0, errno, "cannot change to %s", notify_list->dir);
---- 1091,1095 ----
- while (notify_list != NULL)
- {
-! if (CVS_CHDIR (notify_list->dir) < 0)
- {
- error (0, errno, "cannot change to %s", notify_list->dir);
-***************
-*** 2300,2304 ****
- #endif /* SERVER_FLOWCONTROL */
-
-! dev_null_fd = open ("/dev/null", O_RDONLY);
- if (dev_null_fd < 0)
- {
---- 2300,2304 ----
- #endif /* SERVER_FLOWCONTROL */
-
-! dev_null_fd = CVS_OPEN ("/dev/null", O_RDONLY);
- if (dev_null_fd < 0)
- {
-***************
-*** 2943,2947 ****
- char *mode_string;
-
-! if (stat (file, &sb) < 0)
- {
- /* Not clear to me why the file would fail to exist, but it
---- 2943,2947 ----
- char *mode_string;
-
-! if (CVS_STAT (file, &sb) < 0)
- {
- /* Not clear to me why the file would fail to exist, but it
-***************
-*** 3217,3221 ****
- }
-
-! if (chdir (tempdir) < 0)
- {
- printf ("E Cannot change to directory %s\n", tempdir);
---- 3217,3221 ----
- }
-
-! if (CVS_CHDIR (tempdir) < 0)
- {
- printf ("E Cannot change to directory %s\n", tempdir);
-***************
-*** 3283,3287 ****
- char size_text[80];
-
-! if (stat (file, &sb) < 0)
- {
- if (existence_error (errno))
---- 3283,3287 ----
- char size_text[80];
-
-! if (CVS_STAT (file, &sb) < 0)
- {
- if (existence_error (errno))
-***************
-*** 3370,3374 ****
- pid_t gzip_pid;
-
-! fd = open (file, O_RDONLY, 0);
- if (fd < 0)
- error (1, errno, "reading %s", short_pathname);
---- 3370,3374 ----
- pid_t gzip_pid;
-
-! fd = CVS_OPEN (file, O_RDONLY, 0);
- if (fd < 0)
- error (1, errno, "reading %s", short_pathname);
-***************
-*** 3396,3400 ****
-
- size = sb.st_size;
-! f = fopen (file, "r");
- if (f == NULL)
- error (1, errno, "reading %s", short_pathname);
---- 3396,3400 ----
-
- size = sb.st_size;
-! f = CVS_FOPEN (file, "r");
- if (f == NULL)
- error (1, errno, "reading %s", short_pathname);
-***************
-*** 3427,3431 ****
- join_file. */
- && !joining ())
-! unlink (file);
- }
- else if (scratched_file != NULL && entries_line == NULL)
---- 3427,3431 ----
- join_file. */
- && !joining ())
-! CVS_UNLINK (file);
- }
- else if (scratched_file != NULL && entries_line == NULL)
-***************
-*** 3673,3677 ****
- {
- FILE *f;
-! f = fopen (CVSADM_CIPROG, "w+");
- if (f == NULL)
- {
---- 3673,3677 ----
- {
- FILE *f;
-! f = CVS_FOPEN (CVSADM_CIPROG, "w+");
- if (f == NULL)
- {
-***************
-*** 3702,3706 ****
- {
- FILE *f;
-! f = fopen (CVSADM_UPROG, "w+");
- if (f == NULL)
- {
---- 3702,3706 ----
- {
- FILE *f;
-! f = CVS_FOPEN (CVSADM_UPROG, "w+");
- if (f == NULL)
- {
-***************
-*** 3919,3923 ****
- if (temp_dir == NULL || temp_dir[0] == '\0')
- temp_dir = "/tmp";
-! chdir(temp_dir);
-
- len = strlen (server_temp_dir) + 80;
---- 3919,3923 ----
- if (temp_dir == NULL || temp_dir[0] == '\0')
- temp_dir = "/tmp";
-! CVS_CHDIR (temp_dir);
-
- len = strlen (server_temp_dir) + 80;
-***************
-*** 4160,4164 ****
- memset (linebuf, 0, linelen);
-
-! fp = fopen (filename, "r");
- if (fp == NULL)
- {
---- 4160,4164 ----
- memset (linebuf, 0, linelen);
-
-! fp = CVS_FOPEN (filename, "r");
- if (fp == NULL)
- {
-diff -r -C 2 -P base/cvs-1.6.5/src/tag.c cvs-1.6.5/src/tag.c
-*** base/cvs-1.6.5/src/tag.c Thu Jan 4 06:20:33 1996
---- cvs-1.6.5/src/tag.c Tue Jan 9 05:33:08 1996
-***************
-*** 729,733 ****
- if (save_cwd (&cwd))
- exit (1);
-! if (chdir (repository) < 0)
- error (1, errno, "cannot change to %s directory", repository);
- }
---- 729,733 ----
- if (save_cwd (&cwd))
- exit (1);
-! if (CVS_CHDIR (repository) < 0)
- error (1, errno, "cannot change to %s directory", repository);
- }
-diff -r -C 2 -P base/cvs-1.6.5/src/update.c cvs-1.6.5/src/update.c
-*** base/cvs-1.6.5/src/update.c Thu Jan 4 06:20:34 1996
---- cvs-1.6.5/src/update.c Tue Jan 9 05:33:09 1996
-***************
-*** 255,259 ****
---- 255,261 ----
- if (rq->status == rq_supported)
- {
-+ #ifndef macintosh
- send_arg("-u");
-+ #endif
- }
- break;
-***************
-*** 275,279 ****
-
- if (toplevel_wd[0] != '\0'
-! && chdir (toplevel_wd) < 0)
- {
- error (1, errno, "could not chdir to %s", toplevel_wd);
---- 277,281 ----
-
- if (toplevel_wd[0] != '\0'
-! && CVS_CHDIR (toplevel_wd) < 0)
- {
- error (1, errno, "could not chdir to %s", toplevel_wd);
-***************
-*** 814,818 ****
- /* run the update_prog if there is one */
- if (err == 0 && !pipeout && !noexec &&
-! (fp = fopen (CVSADM_UPROG, "r")) != NULL)
- {
- char *cp;
---- 816,820 ----
- /* run the update_prog if there is one */
- if (err == 0 && !pipeout && !noexec &&
-! (fp = CVS_FOPEN (CVSADM_UPROG, "r")) != NULL)
- {
- char *cp;
-***************
-*** 837,841 ****
- /* FIXME: chdir ("..") loses with symlinks. */
- /* Prune empty dirs on the way out - if necessary */
-! (void) chdir ("..");
- if (update_prune_dirs && isemptydir (dir))
- {
---- 839,843 ----
- /* FIXME: chdir ("..") loses with symlinks. */
- /* Prune empty dirs on the way out - if necessary */
-! (void) CVS_CHDIR ("..");
- if (update_prune_dirs && isemptydir (dir))
- {
-***************
-*** 859,863 ****
- struct dirent *dp;
-
-! if ((dirp = opendir (dir)) == NULL)
- {
- error (0, 0, "cannot open directory %s for empty check", dir);
---- 861,865 ----
- struct dirent *dp;
-
-! if ((dirp = CVS_OPENDIR (dir)) == NULL)
- {
- error (0, 0, "cannot open directory %s for empty check", dir);
-***************
-*** 1207,1211 ****
- else
- {
-! e = fopen (file1, "r");
- if (e == NULL)
- fail = 1;
---- 1209,1213 ----
- else
- {
-! e = CVS_FOPEN (file1, "r");
- if (e == NULL)
- fail = 1;
-***************
-*** 1244,1248 ****
- && !fileattr_get (file, "_watched"))
- xchmod (file2, 1);
-! e = fopen (file2, "r");
- if (e == NULL)
- fail = 1;
---- 1246,1250 ----
- && !fileattr_get (file, "_watched"))
- xchmod (file2, 1);
-! e = CVS_FOPEN (file2, "r");
- if (e == NULL)
- fail = 1;
-***************
-*** 1303,1307 ****
-
- /* Check the diff output to make sure patch will be handle it. */
-! e = fopen (file, "r");
- if (e == NULL)
- error (1, errno, "could not open diff output file %s", file);
---- 1305,1309 ----
-
- /* Check the diff output to make sure patch will be handle it. */
-! e = CVS_FOPEN (file, "r");
- if (e == NULL)
- error (1, errno, "could not open diff output file %s", file);
-***************
-*** 1333,1337 ****
- xvers_ts->tag, xvers_ts->date, NULL);
-
-! if (stat (file2, file_info) < 0)
- error (1, errno, "could not stat %s", file2);
-
---- 1335,1339 ----
- xvers_ts->tag, xvers_ts->date, NULL);
-
-! if (CVS_STAT (file2, file_info) < 0)
- error (1, errno, "could not stat %s", file2);
-
-diff -r -C 2 -P base/cvs-1.6.5/src/vers_ts.c cvs-1.6.5/src/vers_ts.c
-*** base/cvs-1.6.5/src/vers_ts.c Sat Dec 2 06:20:24 1995
---- cvs-1.6.5/src/vers_ts.c Tue Jan 9 05:33:09 1996
-***************
-*** 220,224 ****
- char *cp;
-
-! if (stat (file, &sb) < 0)
- {
- if (! existence_error (errno))
---- 220,224 ----
- char *cp;
-
-! if (CVS_STAT (file, &sb) < 0)
- {
- if (! existence_error (errno))
-***************
-*** 280,284 ****
- char *ts;
-
-! if (stat (file, &sb) < 0)
- {
- ts = NULL;
---- 280,284 ----
- char *ts;
-
-! if (CVS_STAT (file, &sb) < 0)
- {
- ts = NULL;
-diff -r -C 2 -P base/cvs-1.6.5/src/wrapper.c cvs-1.6.5/src/wrapper.c
-*** base/cvs-1.6.5/src/wrapper.c Tue Oct 10 07:20:42 1995
---- cvs-1.6.5/src/wrapper.c Tue Jan 9 05:33:09 1996
-***************
-*** 97,101 ****
-
- /* load the file */
-! if (!(fp = fopen (file, "r")))
- return;
- while (fgets (line, sizeof (line), fp))
---- 97,101 ----
-
- /* load the file */
-! if (!(fp = CVS_FOPEN (file, "r")))
- return;
- while (fgets (line, sizeof (line), fp))
diff --git a/gnu/usr.bin/cvs/src/README-rm-add b/gnu/usr.bin/cvs/src/README-rm-add
deleted file mode 100644
index 87fd7c6d277..00000000000
--- a/gnu/usr.bin/cvs/src/README-rm-add
+++ /dev/null
@@ -1,31 +0,0 @@
-WHAT THE "DEATH SUPPORT" FEATURES DO:
-
-(Some of the death support stuff is documented in the main manual, but
-this file is for stuff which noone has gotten around to adding to the
-main manual yet).
-
-CVS with death support can record when a file is active, or alive, and
-when it is removed, or dead. With this facility you can record the
-history of a file, including the fact that at some point in its life
-the file was removed and then later added.
-
-Files can now be added or removed in a branch and later merged
-into the trunk.
-
- cvs update -A
- touch a b c
- cvs add a b c ; cvs ci -m "added" a b c
- cvs tag -b branchtag
- cvs update -r branchtag
- touch d ; cvs add d
- rm a ; cvs rm a
- cvs ci -m "added d, removed a"
- cvs update -A
- cvs update -jbranchtag
-
-Added and removed files may also be merged between branches.
-
-Files removed in the trunk may be merged into branches.
-
-Files added on the trunk are a special case. They cannot be merged
-into a branch. Instead, simply branch the file by hand.
diff --git a/gnu/usr.bin/cvs/src/checkout.c b/gnu/usr.bin/cvs/src/checkout.c
index c5874645f0e..e876cd22bd2 100644
--- a/gnu/usr.bin/cvs/src/checkout.c
+++ b/gnu/usr.bin/cvs/src/checkout.c
@@ -54,10 +54,10 @@ static const char *const checkout_usage[] =
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, not recursive\n",
"\t-n\tDo not run module program (if any).\n",
- "\t-p\tCheck out files to standard output.\n",
+ "\t-p\tCheck out files to standard output (avoids stickiness).\n",
"\t-s\tLike -c, but include module status.\n",
- "\t-r rev\tCheck out revision or tag. (implies -P)\n",
- "\t-D date\tCheck out revisions as of date. (implies -P)\n",
+ "\t-r rev\tCheck out revision or tag. (implies -P) (is sticky)\n",
+ "\t-D date\tCheck out revisions as of date. (implies -P) (is sticky)\n",
"\t-d dir\tCheck out into dir instead of module name.\n",
"\t-k kopt\tUse RCS kopt -k option on checkout.\n",
"\t-j rev\tMerge in changes made between current revision and rev.\n",
@@ -88,7 +88,9 @@ static int tag_validated = 0;
static char *date = NULL;
static char *join_rev1 = NULL;
static char *join_rev2 = NULL;
+static int join_tags_validated = 0;
static char *preload_update_dir = NULL;
+static char *history_name = NULL;
int
checkout (argc, argv)
@@ -218,8 +220,7 @@ checkout (argc, argv)
if (shorten == -1)
shorten = 0;
- if ((!(cat + status) && argc == 0) || ((cat + status) && argc != 0)
- || (tag && date))
+ if ((!(cat + status) && argc == 0) || ((cat + status) && argc != 0))
usage (valid_usage);
if (where && pipeout)
@@ -269,13 +270,13 @@ checkout (argc, argv)
&& supported_request ("expand-modules"));
if (expand_modules)
- {
+ {
/* This is done here because we need to read responses
from the server before we send the command checkout or
export files. */
client_expand_modules (argc, argv, local);
- }
+ }
if (!run_module_prog) send_arg ("-n");
if (local) send_arg ("-l");
@@ -309,16 +310,16 @@ checkout (argc, argv)
option_with_arg ("-j", join_rev2);
if (expand_modules)
- {
- client_send_expansions (local);
- }
+ {
+ client_send_expansions (local, where);
+ }
else
- {
+ {
int i;
for (i = 0; i < argc; ++i)
- send_arg (argv[i]);
+ send_arg (argv[i]);
client_nonexpanded_setup ();
- }
+ }
send_to_server (strcmp (command_name, "export") == 0 ?
"export\012" : "co\012",
@@ -345,14 +346,14 @@ checkout (argc, argv)
char repository[PATH_MAX];
(void) CVS_MKDIR (where, 0777);
- if (chdir (where) < 0)
+ if ( CVS_CHDIR (where) < 0)
error (1, errno, "cannot chdir to %s", where);
preload_update_dir = xstrdup (where);
where = (char *) NULL;
if (!isfile (CVSADM))
{
- (void) sprintf (repository, "%s/%s/%s", CVSroot, CVSROOTADM,
- CVSNULLREPOS);
+ (void) sprintf (repository, "%s/%s/%s", CVSroot_directory,
+ CVSROOTADM, CVSNULLREPOS);
if (!isfile (repository))
{
mode_t omask;
@@ -365,7 +366,7 @@ checkout (argc, argv)
if (!isdir (repository))
error (1, 0, "there is no repository %s", repository);
- Create_Admin (".", where, repository,
+ Create_Admin (".", preload_update_dir, repository,
(char *) NULL, (char *) NULL);
if (!noexec)
{
@@ -382,6 +383,21 @@ checkout (argc, argv)
}
}
+ /* If we will be calling history_write, work out the name to pass
+ it. */
+ if (strcmp (command_name, "export") != 0 && !pipeout)
+ {
+ if (tag && date)
+ {
+ history_name = xmalloc (strlen (tag) + strlen (date) + 2);
+ sprintf (history_name, "%s:%s", tag, date);
+ }
+ else if (tag)
+ history_name = tag;
+ else
+ history_name = date;
+ }
+
/*
* if where was specified (-d) and we have not taken care of it already
* with the multiple arg stuff, and it was not a simple directory name
@@ -396,7 +412,7 @@ checkout (argc, argv)
slash = strrchr (where, '/');
*slash = '\0';
- if (chdir (where) < 0)
+ if ( CVS_CHDIR (where) < 0)
error (1, errno, "cannot chdir to %s", where);
preload_update_dir = xstrdup (where);
@@ -419,24 +435,32 @@ safe_location ()
{
char current[PATH_MAX];
char hardpath[PATH_MAX+5];
- int hardpathlen;
+ size_t hardpath_len;
int x;
- x = readlink(CVSroot, hardpath, sizeof hardpath - 1);
+ x = readlink(CVSroot_directory, hardpath, sizeof hardpath - 1);
if (x == -1)
{
- strcpy(hardpath, CVSroot);
+ strcpy(hardpath, CVSroot_directory);
}
else
{
hardpath[x] = '\0';
}
getwd (current);
- hardpathlen = strlen (hardpath);
- if (strncmp(current, hardpath, hardpathlen) == 0
- && (current[hardpathlen] == '\0' || current[hardpathlen] == '/'))
+ hardpath_len = strlen (hardpath);
+ if (strncmp (current, hardpath, hardpath_len) == 0)
{
- return (0);
+ if (/* Current is a subdirectory of hardpath. */
+ current[hardpath_len] == '/'
+
+ /* Current is hardpath itself. */
+ || current[hardpath_len] == '\0')
+ return 0;
+ else
+ /* It isn't a problem. For example, current is
+ "/foo/cvsroot-bar" and hardpath is "/foo/cvsroot". */
+ return 1;
}
return (1);
}
@@ -479,7 +503,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
*/
/* set up the repository (maybe) for the bottom directory */
- (void) sprintf (repository, "%s/%s", CVSroot, argv[0]);
+ (void) sprintf (repository, "%s/%s", CVSroot_directory, argv[0]);
/* save the original value of preload_update_dir */
if (preload_update_dir != NULL)
@@ -670,7 +694,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
if (!isdir (repository))
error (1, 0, "there is no repository %s", repository);
- Create_Admin (".", where, repository,
+ Create_Admin (".", preload_update_dir, repository,
(char *) NULL, (char *) NULL);
fp = open_file (CVSADM_ENTSTAT, "w+");
if (fclose(fp) == EOF)
@@ -686,7 +710,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
if (!isdir (repository))
error (1, 0, "there is no repository %s", repository);
- Create_Admin (".", where, repository, tag, date);
+ Create_Admin (".", preload_update_dir, repository, tag, date);
}
}
else
@@ -716,7 +740,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
*/
if (pipeout)
{
- if (chdir (repository) < 0)
+ if ( CVS_CHDIR (repository) < 0)
{
error (0, errno, "cannot chdir to %s", repository);
free (preload_update_dir);
@@ -741,11 +765,19 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
}
}
- if (tag != NULL || date != NULL)
+ if (tag != NULL || date != NULL || join_rev1 != NULL)
which |= W_ATTIC;
- /* FIXME: We don't call tag_check_valid on join_rev1 and join_rev2
- yet (make sure to handle ':' correctly if we do, though). */
+ if (! join_tags_validated)
+ {
+ if (join_rev1 != NULL)
+ tag_check_valid_join (join_rev1, *pargc - 1, argv + 1, 0, aflag,
+ repository);
+ if (join_rev2 != NULL)
+ tag_check_valid_join (join_rev2, *pargc - 1, argv + 1, 0, aflag,
+ repository);
+ join_tags_validated = 1;
+ }
/*
* if we are going to be recursive (building dirs), go ahead and call the
@@ -755,7 +787,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
if (!(local_specified || *pargc > 1))
{
if (strcmp (command_name, "export") != 0 && !pipeout)
- history_write ('O', preload_update_dir, tag ? tag : date, where,
+ history_write ('O', preload_update_dir, history_name, where,
repository);
err += do_update (0, (char **) NULL, options, tag, date,
force_tag_match, 0 /* !local */ ,
@@ -777,17 +809,28 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
for (i = 1; i < *pargc; i++)
{
char *line;
- char *user;
Vers_TS *vers;
-
- user = argv[i];
- vers = Version_TS (repository, options, tag, date, user,
- force_tag_match, 0, entries, (RCSNode *) NULL);
+ struct file_info finfo;
+
+ memset (&finfo, 0, sizeof finfo);
+ finfo.file = argv[i];
+ /* Shouldn't be used, so set to arbitrary value. */
+ finfo.update_dir = NULL;
+ finfo.fullname = argv[i];
+ finfo.repository = repository;
+ finfo.entries = entries;
+ /* The rcs slot is needed to get the options from the RCS
+ file */
+ finfo.rcs = RCS_parse (finfo.file, repository);
+
+ vers = Version_TS (&finfo, options, tag, date,
+ force_tag_match, 0);
if (vers->ts_user == NULL)
{
- line = xmalloc (strlen (user) + 15);
- (void) sprintf (line, "Initial %s", user);
- Register (entries, user, vers->vn_rcs ? vers->vn_rcs : "0",
+ line = xmalloc (strlen (finfo.file) + 15);
+ (void) sprintf (line, "Initial %s", finfo.file);
+ Register (entries, finfo.file,
+ vers->vn_rcs ? vers->vn_rcs : "0",
line, vers->options, vers->tag,
vers->date, (char *) 0);
free (line);
@@ -800,7 +843,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
/* Don't log "export", just regular "checkouts" */
if (strcmp (command_name, "export") != 0 && !pipeout)
- history_write ('O', preload_update_dir, (tag ? tag : date), where,
+ history_write ('O', preload_update_dir, history_name, where,
repository);
/* go ahead and call update now that everything is set */
@@ -854,8 +897,9 @@ build_dirs_and_chdir (dir, prepath, realdir, sticky)
{
*slash = '\0';
*slash2 = '\0';
+ Subdir_Register ((List *) NULL, (char *) NULL, cp);
(void) CVS_MKDIR (cp, 0777);
- if (chdir (cp) < 0)
+ if ( CVS_CHDIR (cp) < 0)
{
error (0, errno, "cannot chdir to %s", cp);
return (1);
@@ -882,8 +926,9 @@ build_dirs_and_chdir (dir, prepath, realdir, sticky)
*slash = '/';
*slash2 = '/';
}
+ Subdir_Register ((List *) NULL, (char *) NULL, cp);
(void) CVS_MKDIR (cp, 0777);
- if (chdir (cp) < 0)
+ if ( CVS_CHDIR (cp) < 0)
{
error (0, errno, "cannot chdir to %s", cp);
return (1);
diff --git a/gnu/usr.bin/cvs/src/commit.c b/gnu/usr.bin/cvs/src/commit.c
index ac81790e934..5d9c804e9b3 100644
--- a/gnu/usr.bin/cvs/src/commit.c
+++ b/gnu/usr.bin/cvs/src/commit.c
@@ -14,34 +14,44 @@
*
*/
+#include <assert.h>
#include "cvs.h"
#include "getline.h"
#include "edit.h"
#include "fileattr.h"
-static Dtype check_direntproc PROTO((char *dir, char *repos, char *update_dir));
-static int check_fileproc PROTO((struct file_info *finfo));
-static int check_filesdoneproc PROTO((int err, char *repos, char *update_dir));
+static Dtype check_direntproc PROTO ((void *callerdat, char *dir,
+ char *repos, char *update_dir,
+ List *entries));
+static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo));
+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));
-static Dtype commit_direntproc PROTO((char *dir, char *repos, char *update_dir));
-static int commit_dirleaveproc PROTO((char *dir, int err, char *update_dir));
-static int commit_fileproc PROTO((struct file_info *finfo));
-static int commit_filesdoneproc PROTO((int err, char *repository, char *update_dir));
-static int finaladd PROTO((char *file, char *revision, char *tag,
- char *options, char *update_dir,
- char *repository, List *entries));
+static Dtype commit_direntproc PROTO ((void *callerdat, char *dir,
+ char *repos, char *update_dir,
+ List *entries));
+static int commit_dirleaveproc PROTO ((void *callerdat, char *dir,
+ int err, char *update_dir,
+ List *entries));
+static int commit_fileproc PROTO ((void *callerdat, struct file_info *finfo));
+static int commit_filesdoneproc PROTO ((void *callerdat, int err,
+ char *repository, char *update_dir,
+ List *entries));
+static int finaladd PROTO((struct file_info *finfo, char *revision, char *tag,
+ char *options));
static int findmaxrev PROTO((Node * p, void *closure));
-static int lock_RCS PROTO((char *user, char *rcs, char *rev, char *repository));
-static int lockrcsfile PROTO((char *file, char *repository, char *rev));
+static int lock_RCS PROTO((char *user, RCSNode *rcs, char *rev,
+ char *repository));
static int precommit_list_proc PROTO((Node * p, void *closure));
static int precommit_proc PROTO((char *repository, char *filter));
-static int remove_file PROTO((char *file, char *repository, char *tag,
- char *message, List *entries, RCSNode *rcsnode));
+static int remove_file PROTO ((struct file_info *finfo, char *tag,
+ char *message));
static void fix_rcs_modes PROTO((char *rcs, char *user));
static void fixaddfile PROTO((char *file, char *repository));
-static void fixbranch PROTO((char *file, char *repository, char *branch));
-static void unlockrcs PROTO((char *file, char *repository));
+static void fixbranch PROTO((RCSNode *, char *branch));
+static void unlockrcs PROTO((RCSNode *rcs));
static void ci_delproc PROTO((Node *p));
static void masterlist_delproc PROTO((Node *p));
static void locate_rcs PROTO((char *file, char *repository, char *rcs));
@@ -85,37 +95,146 @@ static const char *const commit_usage[] =
};
#ifdef CLIENT_SUPPORT
+/* Identify a file which needs "? foo" or a Questionable request. */
+struct question {
+ /* The two fields for the Directory request. */
+ char *dir;
+ char *repos;
+
+ /* The file name. */
+ char *file;
+
+ struct question *next;
+};
+
struct find_data {
List *ulist;
int argc;
char **argv;
+
+ /* This is used from dirent to filesdone time, for each directory,
+ to make a list of files we have already seen. */
+ List *ignlist;
+
+ /* Linked list of files which need "? foo" or a Questionable request. */
+ struct question *questionables;
+
+ /* Only good within functions called from the filesdoneproc. Stores
+ the repository (pointer into storage managed by the recursion
+ processor. */
+ char *repository;
};
-/* Pass as a static until we get around to fixing start_recursion to
- pass along a void * where we can stash it. */
-struct find_data *find_data_static;
+static Dtype find_dirent_proc PROTO ((void *callerdat, char *dir,
+ char *repository, char *update_dir,
+ List *entries));
-static int find_fileproc PROTO ((struct file_info *finfo));
+static Dtype
+find_dirent_proc (callerdat, dir, repository, update_dir, entries)
+ void *callerdat;
+ char *dir;
+ char *repository;
+ char *update_dir;
+ List *entries;
+{
+ struct find_data *find_data = (struct find_data *)callerdat;
+
+ /* initialize the ignore list for this directory */
+ find_data->ignlist = getlist ();
+ return R_PROCESS;
+}
+
+/* Here as a static until we get around to fixing ignore_files to pass
+ it along as an argument. */
+static struct find_data *find_data_static;
+
+static void find_ignproc PROTO ((char *, char *));
+
+static void
+find_ignproc (file, dir)
+ char *file;
+ char *dir;
+{
+ struct question *p;
+
+ p = (struct question *) xmalloc (sizeof (struct question));
+ p->dir = xstrdup (dir);
+ p->repos = xstrdup (find_data_static->repository);
+ p->file = xstrdup (file);
+ p->next = find_data_static->questionables;
+ find_data_static->questionables = p;
+}
+
+static int find_filesdoneproc PROTO ((void *callerdat, int err,
+ char *repository, char *update_dir,
+ List *entries));
+
+static int
+find_filesdoneproc (callerdat, err, repository, update_dir, entries)
+ void *callerdat;
+ int err;
+ char *repository;
+ char *update_dir;
+ List *entries;
+{
+ struct find_data *find_data = (struct find_data *)callerdat;
+ find_data->repository = repository;
+
+ /* if this directory has an ignore list, process it then free it */
+ if (find_data->ignlist)
+ {
+ find_data_static = find_data;
+ ignore_files (find_data->ignlist, entries, update_dir, find_ignproc);
+ dellist (&find_data->ignlist);
+ }
+
+ find_data->repository = NULL;
+
+ return err;
+}
+
+static int find_fileproc PROTO ((void *callerdat, struct file_info *finfo));
/* Machinery to find out what is modified, added, and removed. It is
possible this should be broken out into a new client_classify function;
merging it with classify_file is almost sure to be a mess, though,
because classify_file has all kinds of repository processing. */
static int
-find_fileproc (finfo)
+find_fileproc (callerdat, finfo)
+ void *callerdat;
struct file_info *finfo;
{
Vers_TS *vers;
enum classify_type status;
Node *node;
- struct find_data *args = find_data_static;
+ struct find_data *args = (struct find_data *)callerdat;
+ struct logfile_info *data;
+ struct file_info xfinfo;
+
+ /* if this directory has an ignore list, add this file to it */
+ if (args->ignlist)
+ {
+ Node *p;
+
+ p = getnode ();
+ p->type = FILES;
+ p->key = xstrdup (finfo->file);
+ if (addnode (args->ignlist, p) != 0)
+ freenode (p);
+ }
- vers = Version_TS ((char *)NULL, (char *)NULL, (char *)NULL,
- (char *)NULL,
- finfo->file, 0, 0, finfo->entries, (RCSNode *)NULL);
+ xfinfo = *finfo;
+ xfinfo.repository = NULL;
+ xfinfo.rcs = NULL;
+
+ vers = Version_TS (&xfinfo, NULL, NULL, NULL, 0, 0);
if (vers->ts_user == NULL
&& vers->vn_user != NULL
&& vers->vn_user[0] == '-')
+ /* FIXME: If vn_user is starts with "-" but ts_user is
+ non-NULL, what classify_file does is print "%s should be
+ removed and is still there". I'm not sure what it does
+ then. We probably should do the same. */
status = T_REMOVED;
else if (vers->vn_user == NULL)
{
@@ -129,6 +248,9 @@ find_fileproc (finfo)
else if (vers->ts_user != NULL
&& vers->vn_user != NULL
&& vers->vn_user[0] == '0')
+ /* FIXME: If vn_user is "0" but ts_user is NULL, what classify_file
+ does is print "new-born %s has disappeared" and removes the entry.
+ We probably should do the same. */
status = T_ADDED;
else if (vers->ts_user != NULL
&& vers->ts_rcs != NULL
@@ -146,13 +268,18 @@ find_fileproc (finfo)
node = getnode ();
node->key = xstrdup (finfo->fullname);
+ data = (struct logfile_info *) xmalloc (sizeof (struct logfile_info));
+ data->type = status;
+ data->tag = xstrdup (vers->tag);
+
node->type = UPDATE;
node->delproc = update_delproc;
- node->data = (char *) status;
+ node->data = (char *) data;
(void)addnode (args->ulist, node);
++args->argc;
+ freevers_ts (&vers);
return 0;
}
@@ -270,7 +397,7 @@ commit (argc, argv)
error (1, 0, "cannot specify both a message and a log file");
/* FIXME: Why is this binary? Needs more investigation. */
- if ((logfd = open (logfile, O_RDONLY | OPEN_BINARY)) < 0)
+ if ((logfd = CVS_OPEN (logfile, O_RDONLY | OPEN_BINARY)) < 0)
error (1, errno, "cannot open log file %s", logfile);
if (fstat(logfd, &statbuf) < 0)
@@ -294,21 +421,25 @@ commit (argc, argv)
ign_setup ();
- /* Note that we don't do ignore file processing here, and we
- don't call ignore_files. This means that we won't print "?
- foo" for stray files. Sounds OK, the doc only promises
- that update does that. */
find_args.ulist = getlist ();
find_args.argc = 0;
- find_data_static = &find_args;
- err = start_recursion (find_fileproc, (FILESDONEPROC) NULL,
- (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL,
- argc, argv, local, W_LOCAL, 0, 0,
- (char *)NULL, 0, 0);
+ find_args.questionables = NULL;
+ find_args.ignlist = NULL;
+ find_args.repository = NULL;
+
+ err = start_recursion (find_fileproc, find_filesdoneproc,
+ find_dirent_proc, (DIRLEAVEPROC) NULL,
+ (void *)&find_args,
+ argc, argv, local, W_LOCAL, 0, 0,
+ (char *)NULL, 0);
if (err)
error (1, 0, "correct above errors first!");
if (find_args.argc == 0)
+ /* Nothing to commit. Exit now without contacting the
+ server (note that this means that we won't print "?
+ foo" for files which merit it, because we don't know
+ what is in the CVSROOT/cvsignore file). */
return 0;
/* Now we keep track of which files we actually are going to
@@ -319,12 +450,16 @@ commit (argc, argv)
find_args.argc = 0;
walklist (find_args.ulist, copy_ulist, &find_args);
- /*
- * Do this before calling do_editor; don't ask for a log
- * message if we can't talk to the server. But do it after we
- * have made the checks that we can locally (to more quickly
- * catch syntax errors, the case where no files are modified,
- * added or removed, etc.). */
+ /* Do this before calling do_editor; don't ask for a log
+ message if we can't talk to the server. But do it after we
+ have made the checks that we can locally (to more quickly
+ catch syntax errors, the case where no files are modified,
+ added or removed, etc.).
+
+ On the other hand, calling start_server before do_editor
+ means that we chew up server resources the whole time that
+ the user has the editor open (hours or days if the user
+ forgets about it), which seems dubious. */
start_server ();
/*
@@ -337,6 +472,47 @@ commit (argc, argv)
/* We always send some sort of message, even if empty. */
option_with_arg ("-m", message);
+ /* OK, now process all the questionable files we have been saving
+ up. */
+ {
+ struct question *p;
+ struct question *q;
+
+ p = find_args.questionables;
+ while (p != NULL)
+ {
+ if (ign_inhibit_server || !supported_request ("Questionable"))
+ {
+ cvs_output ("? ", 2);
+ if (p->dir[0] != '\0')
+ {
+ cvs_output (p->dir, 0);
+ cvs_output ("/", 1);
+ }
+ cvs_output (p->file, 0);
+ cvs_output ("\n", 1);
+ }
+ else
+ {
+ send_to_server ("Directory ", 0);
+ send_to_server (p->dir[0] == '\0' ? "." : p->dir, 0);
+ send_to_server ("\012", 1);
+ send_to_server (p->repos, 0);
+ send_to_server ("\012", 1);
+
+ send_to_server ("Questionable ", 0);
+ send_to_server (p->file, 0);
+ send_to_server ("\012", 1);
+ }
+ free (p->dir);
+ free (p->repos);
+ free (p->file);
+ q = p->next;
+ free (p);
+ p = q;
+ }
+ }
+
if (local)
send_arg("-l");
if (force_ci)
@@ -378,9 +554,8 @@ commit (argc, argv)
* Run the recursion processor to verify the files are all up-to-date
*/
err = start_recursion (check_fileproc, check_filesdoneproc,
- check_direntproc, (DIRLEAVEPROC) NULL, argc,
- argv, local, W_LOCAL, aflag, 0, (char *) NULL, 1,
- 0);
+ check_direntproc, (DIRLEAVEPROC) NULL, NULL, argc,
+ argv, local, W_LOCAL, aflag, 0, (char *) NULL, 1);
if (err)
{
lock_tree_cleanup ();
@@ -392,9 +567,9 @@ commit (argc, argv)
*/
if (noexec == 0)
err = start_recursion (commit_fileproc, commit_filesdoneproc,
- commit_direntproc, commit_dirleaveproc,
+ commit_direntproc, commit_dirleaveproc, NULL,
argc, argv, local, W_LOCAL, aflag, 0,
- (char *) NULL, 1, 0);
+ (char *) NULL, 1);
/*
* Unlock all the dirs and clean up
@@ -422,7 +597,8 @@ commit (argc, argv)
*/
/* ARGSUSED */
static int
-check_fileproc (finfo)
+check_fileproc (callerdat, finfo)
+ void *callerdat;
struct file_info *finfo;
{
Ctype status;
@@ -431,6 +607,7 @@ check_fileproc (finfo)
List *ulist, *cilist;
Vers_TS *vers;
struct commit_info *ci;
+ struct logfile_info *li;
int save_noexec, save_quiet, save_really_quiet;
save_noexec = noexec;
@@ -444,19 +621,16 @@ check_fileproc (finfo)
/* If the tag is for the trunk, make sure we're at the head */
if (numdots (tag) < 2)
{
- status = Classify_File (finfo->file, (char *) NULL, (char *) NULL,
- (char *) NULL, 1, aflag, finfo->repository,
- finfo->entries, finfo->rcs, &vers, finfo->update_dir, 0);
+ status = Classify_File (finfo, (char *) NULL, (char *) NULL,
+ (char *) NULL, 1, aflag, &vers, 0);
if (status == T_UPTODATE || status == T_MODIFIED ||
status == T_ADDED)
{
Ctype xstatus;
freevers_ts (&vers);
- xstatus = Classify_File (finfo->file, tag, (char *) NULL,
- (char *) NULL, 1, aflag, finfo->repository,
- finfo->entries, finfo->rcs, &vers, finfo->update_dir,
- 0);
+ xstatus = Classify_File (finfo, tag, (char *) NULL,
+ (char *) NULL, 1, aflag, &vers, 0);
if (xstatus == T_REMOVE_ENTRY)
status = T_MODIFIED;
else if (status == T_MODIFIED && xstatus == T_CONFLICT)
@@ -479,19 +653,16 @@ check_fileproc (finfo)
cp = strrchr (xtag, '.');
*cp = '\0';
}
- status = Classify_File (finfo->file, xtag, (char *) NULL,
- (char *) NULL, 1, aflag, finfo->repository,
- finfo->entries, finfo->rcs, &vers, finfo->update_dir, 0);
+ status = Classify_File (finfo, xtag, (char *) NULL,
+ (char *) NULL, 1, aflag, &vers, 0);
if ((status == T_REMOVE_ENTRY || status == T_CONFLICT)
&& (cp = strrchr (xtag, '.')) != NULL)
{
/* pluck one more dot off the revision */
*cp = '\0';
freevers_ts (&vers);
- status = Classify_File (finfo->file, xtag, (char *) NULL,
- (char *) NULL, 1, aflag, finfo->repository,
- finfo->entries, finfo->rcs, &vers, finfo->update_dir,
- 0);
+ status = Classify_File (finfo, xtag, (char *) NULL,
+ (char *) NULL, 1, aflag, &vers, 0);
if (status == T_UPTODATE || status == T_REMOVE_ENTRY)
status = T_MODIFIED;
}
@@ -502,9 +673,8 @@ check_fileproc (finfo)
}
}
else
- status = Classify_File (finfo->file, tag, (char *) NULL, (char *) NULL,
- 1, 0, finfo->repository, finfo->entries, finfo->rcs, &vers,
- finfo->update_dir, 0);
+ status = Classify_File (finfo, tag, (char *) NULL, (char *) NULL,
+ 1, 0, &vers, 0);
noexec = save_noexec;
quiet = save_quiet;
really_quiet = save_really_quiet;
@@ -538,7 +708,8 @@ check_fileproc (finfo)
* - can't have a sticky tag that is not a branch
* Also,
* - if status is T_REMOVED, can't have a numeric tag
- * - if status is T_ADDED, rcs file must not exist
+ * - if status is T_ADDED, rcs file must not exist unless on
+ * a branch
* - if status is T_ADDED, can't have a non-trunk numeric rev
* - if status is T_MODIFIED and a Conflict marker exists, don't
* allow the commit if timestamp is identical or if we find
@@ -632,18 +803,22 @@ check_fileproc (finfo)
}
if (status == T_ADDED)
{
- char rcs[PATH_MAX];
-
- /* Don't look in the attic; if it exists there we will
- move it back out in checkaddfile. */
- sprintf(rcs, "%s/%s%s", finfo->repository, finfo->file, RCSEXT);
- if (isreadable (rcs))
+ if (vers->tag == NULL)
{
- error (0, 0,
- "cannot add file `%s' when RCS file `%s' already exists",
- finfo->fullname, rcs);
- freevers_ts (&vers);
- return (1);
+ char rcs[PATH_MAX];
+
+ /* Don't look in the attic; if it exists there we
+ will move it back out in checkaddfile. */
+ sprintf(rcs, "%s/%s%s", finfo->repository, finfo->file,
+ RCSEXT);
+ if (isreadable (rcs))
+ {
+ error (0, 0,
+ "cannot add file `%s' when RCS file `%s' already exists",
+ finfo->fullname, rcs);
+ freevers_ts (&vers);
+ return (1);
+ }
}
if (vers->tag && isdigit (*vers->tag) &&
numdots (vers->tag) > 1)
@@ -689,7 +864,11 @@ check_fileproc (finfo)
p->key = xstrdup (finfo->file);
p->type = UPDATE;
p->delproc = update_delproc;
- p->data = (char *) status;
+ li = ((struct logfile_info *)
+ xmalloc (sizeof (struct logfile_info)));
+ li->type = status;
+ li->tag = xstrdup (vers->tag);
+ p->data = (char *) li;
(void) addnode (ulist, p);
p = getnode ();
@@ -730,10 +909,12 @@ check_fileproc (finfo)
*/
/* ARGSUSED */
static Dtype
-check_direntproc (dir, repos, update_dir)
+check_direntproc (callerdat, dir, repos, update_dir, entries)
+ void *callerdat;
char *dir;
char *repos;
char *update_dir;
+ List *entries;
{
if (!quiet)
error (0, 0, "Examining %s", update_dir);
@@ -749,8 +930,12 @@ precommit_list_proc (p, closure)
Node *p;
void *closure;
{
- if (p->data == (char *) T_ADDED || p->data == (char *) T_MODIFIED ||
- p->data == (char *) T_REMOVED)
+ struct logfile_info *li;
+
+ li = (struct logfile_info *) p->data;
+ if (li->type == T_ADDED
+ || li->type == T_MODIFIED
+ || li->type == T_REMOVED)
{
run_arg (p->key);
}
@@ -797,10 +982,12 @@ precommit_proc (repository, filter)
*/
/* ARGSUSED */
static int
-check_filesdoneproc (err, repos, update_dir)
+check_filesdoneproc (callerdat, err, repos, update_dir, entries)
+ void *callerdat;
int err;
char *repos;
char *update_dir;
+ List *entries;
{
int n;
Node *p;
@@ -834,14 +1021,14 @@ static char sbranch[PATH_MAX];
/* ARGSUSED */
static int
-commit_fileproc (finfo)
+commit_fileproc (callerdat, finfo)
+ void *callerdat;
struct file_info *finfo;
{
Node *p;
int err = 0;
List *ulist, *cilist;
struct commit_info *ci;
- char rcs[PATH_MAX];
if (finfo->update_dir[0] == '\0')
p = findnode (mulist, ".");
@@ -875,9 +1062,12 @@ commit_fileproc (finfo)
ci = (struct commit_info *) p->data;
if (ci->status == T_MODIFIED)
{
- if (lockrcsfile (finfo->file, finfo->repository, ci->rev) != 0)
+ if (finfo->rcs == NULL)
+ error (1, 0, "internal error: no parsed RCS file");
+ if (lock_RCS (finfo->file, finfo->rcs, ci->rev,
+ finfo->repository) != 0)
{
- unlockrcs (finfo->file, finfo->repository);
+ unlockrcs (finfo->rcs);
err = 1;
goto out;
}
@@ -896,15 +1086,17 @@ commit_fileproc (finfo)
Since the branch test was done in check_fileproc for
modified files, we need to stub it in again here. */
- if (ci->tag) {
- locate_rcs (finfo->file, finfo->repository, rcs);
+ if (ci->tag)
+ {
+ if (finfo->rcs == NULL)
+ error (1, 0, "internal error: no parsed RCS file");
ci->rev = RCS_whatbranch (finfo->rcs, ci->tag);
- err = Checkin ('A', finfo->file, finfo->update_dir, finfo->repository, rcs, ci->rev,
- ci->tag, ci->options, message, finfo->entries);
+ err = Checkin ('A', finfo, finfo->rcs->path, ci->rev,
+ ci->tag, ci->options, message);
if (err != 0)
{
- unlockrcs (finfo->file, finfo->repository);
- fixbranch (finfo->file, finfo->repository, sbranch);
+ unlockrcs (finfo->rcs);
+ fixbranch (finfo->rcs, sbranch);
}
(void) time (&last_register_time);
@@ -932,36 +1124,37 @@ commit_fileproc (finfo)
}
/* XXX - an added file with symbolic -r should add tag as well */
- err = finaladd (finfo->file, ci->rev ? ci->rev : xrev, ci->tag, ci->options,
- finfo->update_dir, finfo->repository, finfo->entries);
+ err = finaladd (finfo, ci->rev ? ci->rev : xrev, ci->tag, ci->options);
if (xrev)
free (xrev);
}
else if (ci->status == T_MODIFIED)
{
- locate_rcs (finfo->file, finfo->repository, rcs);
- err = Checkin ('M', finfo->file, finfo->update_dir, finfo->repository,
- rcs, ci->rev, ci->tag,
- ci->options, message, finfo->entries);
+ err = Checkin ('M', finfo,
+ finfo->rcs->path, ci->rev, ci->tag,
+ ci->options, message);
(void) time (&last_register_time);
if (err != 0)
{
- unlockrcs (finfo->file, finfo->repository);
- fixbranch (finfo->file, finfo->repository, sbranch);
+ unlockrcs (finfo->rcs);
+ fixbranch (finfo->rcs, sbranch);
}
}
else if (ci->status == T_REMOVED)
{
- err = remove_file (finfo->file, finfo->repository, ci->tag, message,
- finfo->entries, finfo->rcs);
+ err = remove_file (finfo, ci->tag, message);
#ifdef SERVER_SUPPORT
if (server_active) {
server_scratch_entry_only ();
- server_updated (finfo->file, finfo->update_dir, finfo->repository,
+ server_updated (finfo,
+ NULL,
+
/* Doesn't matter, it won't get checked. */
- SERVER_UPDATED, (struct stat *) NULL,
+ SERVER_UPDATED,
+
+ (struct stat *) NULL,
(unsigned char *) NULL);
}
#endif
@@ -988,12 +1181,13 @@ out:
*/
/* ARGSUSED */
static int
-commit_filesdoneproc (err, repository, update_dir)
+commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
+ void *callerdat;
int err;
char *repository;
char *update_dir;
+ List *entries;
{
- char *xtag = (char *) NULL;
Node *p;
List *ulist;
@@ -1005,21 +1199,17 @@ commit_filesdoneproc (err, repository, update_dir)
got_message = 0;
- /* see if we need to specify a per-directory or -r option tag */
- if (tag == NULL)
- ParseTag (&xtag, (char **) NULL);
- Update_Logfile (repository, message, tag ? tag : xtag, (FILE *) 0, ulist);
- if (xtag)
- free (xtag);
+ Update_Logfile (repository, message, (FILE *) 0, ulist);
/* Build the administrative files if necessary. */
{
char *p;
- if (strncmp (CVSroot, repository, strlen (CVSroot)) != 0)
- error (0, 0, "internal error: repository doesn't begin with root");
- p = repository + strlen (CVSroot);
+ 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);
+ p = repository + strlen (CVSroot_directory);
if (*p == '/')
++p;
if (strcmp ("CVSROOT", p) == 0)
@@ -1042,7 +1232,7 @@ commit_filesdoneproc (err, repository, update_dir)
{
FILE *fp;
- if ((fp = fopen (CVSADM_CIPROG, "r")) != NULL)
+ if ((fp = CVS_FOPEN (CVSADM_CIPROG, "r")) != NULL)
{
char *line;
int line_length;
@@ -1092,10 +1282,12 @@ commit_filesdoneproc (err, repository, update_dir)
*/
/* ARGSUSED */
static Dtype
-commit_direntproc (dir, repos, update_dir)
+commit_direntproc (callerdat, dir, repos, update_dir, entries)
+ void *callerdat;
char *dir;
char *repos;
char *update_dir;
+ List *entries;
{
Node *p;
List *ulist;
@@ -1132,10 +1324,12 @@ commit_direntproc (dir, repos, update_dir)
*/
/* ARGSUSED */
static int
-commit_dirleaveproc (dir, err, update_dir)
+commit_dirleaveproc (callerdat, dir, err, update_dir, entries)
+ void *callerdat;
char *dir;
int err;
char *update_dir;
+ List *entries;
{
/* update the per-directory tag info */
if (err == 0 && write_dirtag != NULL)
@@ -1164,6 +1358,8 @@ findmaxrev (p, closure)
Entnode *entdata;
entdata = (Entnode *) p->data;
+ if (entdata->type != ENT_FILE)
+ return (0);
cp = strchr (entdata->version, '.');
if (cp != NULL)
*cp = '\0';
@@ -1182,17 +1378,13 @@ findmaxrev (p, closure)
* link to keep it relative after we move it into the attic.
*/
static int
-remove_file (file, repository, tag, message, entries, rcsnode)
- char *file;
- char *repository;
+remove_file (finfo, tag, message)
+ struct file_info *finfo;
char *tag;
char *message;
- List *entries;
- RCSNode *rcsnode;
{
mode_t omask;
int retcode;
- char rcs[PATH_MAX];
char *tmp;
int branch;
@@ -1200,6 +1392,7 @@ remove_file (file, repository, tag, message, entries, rcsnode)
char *corev;
char *rev;
char *prev_rev;
+ char *old_path;
corev = NULL;
rev = NULL;
@@ -1207,20 +1400,22 @@ remove_file (file, repository, tag, message, entries, rcsnode)
retcode = 0;
- locate_rcs (file, repository, rcs);
+ if (finfo->rcs == NULL)
+ error (1, 0, "internal error: no parsed RCS file");
branch = 0;
- if (tag && !(branch = RCS_isbranch (rcsnode, tag)))
+ if (tag && !(branch = RCS_isbranch (finfo->rcs, tag)))
{
/* a symbolic tag is specified; just remove the tag from the file */
- if ((retcode = RCS_deltag (rcs, tag, 1)) != 0)
+ if ((retcode = RCS_deltag (finfo->rcs, tag, 1)) != 0)
{
if (!quiet)
error (0, retcode == -1 ? errno : 0,
- "failed to remove tag `%s' from `%s'", tag, rcs);
+ "failed to remove tag `%s' from `%s'", tag,
+ finfo->fullname);
return (1);
}
- Scratch_Entry (entries, file);
+ Scratch_Entry (finfo->entries, finfo->file);
return (0);
}
@@ -1228,32 +1423,27 @@ remove_file (file, repository, tag, message, entries, rcsnode)
/* commit a new, dead revision. */
/* Print message indicating that file is going to be removed. */
- (void) printf ("Removing %s;\n", file);
+ (void) printf ("Removing %s;\n", finfo->fullname);
rev = NULL;
- lockflag = RCS_FLAGS_LOCK;
+ lockflag = 1;
if (branch)
{
char *branchname;
- rev = RCS_whatbranch (rcsnode, tag);
+ rev = RCS_whatbranch (finfo->rcs, tag);
if (rev == NULL)
{
error (0, 0, "cannot find branch \"%s\".", tag);
return (1);
}
- if (rcsnode == NULL)
- {
- error (0, 0, "boy, I'm confused.");
- return (1);
- }
- branchname = RCS_getbranch (rcsnode, rev, 1);
+ branchname = RCS_getbranch (finfo->rcs, rev, 1);
if (branchname == NULL)
{
/* no revision exists on this branch. use the previous
revision but do not lock. */
- corev = RCS_gettag (rcsnode, tag, 1, 0);
+ corev = RCS_gettag (finfo->rcs, tag, 1, (int *) NULL);
prev_rev = xstrdup(rev);
lockflag = 0;
} else
@@ -1265,24 +1455,18 @@ remove_file (file, repository, tag, message, entries, rcsnode)
} else /* Not a branch */
{
-
/* Get current head revision of file. */
- if (rcsnode == NULL)
- {
- error (0, 0, "could not find parsed rcsfile %s", file);
- return (1);
- }
- prev_rev = RCS_head (rcsnode);
+ 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 (rcs, NULL) != 0)
+ if (RCS_setbranch (finfo->rcs, NULL) != 0)
{
error (0, 0, "cannot change branch to default for %s",
- rcs);
+ finfo->fullname);
return (1);
}
}
@@ -1293,71 +1477,82 @@ remove_file (file, repository, tag, message, entries, rcsnode)
temp directory which is the kludgy way in which server.c
tells time_stamp that the file is no longer around. Remove
it so we can create temp files with that name (ignore errors). */
- unlink_file (file);
+ unlink_file (finfo->file);
}
#endif
/* check something out. Generally this is the head. If we have a
- particular rev, then name it. except when creating a branch,
- lock the rev we're checking out. */
- retcode = RCS_checkout (rcs, "", rev ? corev : NULL, NULL, RUN_TTY,
- lockflag, 1);
+ particular rev, then name it. */
+ retcode = RCS_checkout (finfo->rcs, finfo->file, rev ? corev : NULL,
+ (char *) NULL, (char *) NULL, RUN_TTY);
if (retcode != 0)
{
if (!quiet)
error (0, retcode == -1 ? errno : 0,
- "failed to check out `%s'", rcs);
+ "failed to check out `%s'", finfo->fullname);
return (1);
}
+ /* Except when we are creating a branch, lock the revision so that
+ we can check in the new revision. */
+ if (lockflag)
+ RCS_lock (finfo->rcs, rev ? corev : NULL, 0);
+
if (corev != NULL)
free (corev);
- retcode = RCS_checkin (rcs, NULL, message, rev, RCS_FLAGS_DEAD, 1);
+ retcode = RCS_checkin (finfo->rcs->path, finfo->file, message, rev,
+ RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
if (retcode != 0)
{
if (!quiet)
error (0, retcode == -1 ? errno : 0,
- "failed to commit dead revision for `%s'", rcs);
+ "failed to commit dead revision for `%s'", finfo->fullname);
return (1);
}
if (rev != NULL)
free (rev);
+ old_path = finfo->rcs->path;
if (!branch)
{
/* this was the head; really move it into the Attic */
- tmp = xmalloc(strlen(repository) +
+ tmp = xmalloc(strlen(finfo->repository) +
sizeof('/') +
sizeof(CVSATTIC) +
sizeof('/') +
- strlen(file) +
+ strlen(finfo->file) +
sizeof(RCSEXT) + 1);
- (void) sprintf (tmp, "%s/%s", repository, CVSATTIC);
+ (void) sprintf (tmp, "%s/%s", finfo->repository, CVSATTIC);
omask = umask (cvsumask);
(void) CVS_MKDIR (tmp, 0777);
(void) umask (omask);
- (void) sprintf (tmp, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
+ (void) sprintf (tmp, "%s/%s/%s%s", finfo->repository, CVSATTIC, finfo->file, RCSEXT);
- if (strcmp (rcs, tmp) != 0
- && rename (rcs, tmp) == -1
- && (isreadable (rcs) || !isreadable (tmp)))
+ if (strcmp (finfo->rcs->path, tmp) != 0
+ && CVS_RENAME (finfo->rcs->path, tmp) == -1
+ && (isreadable (finfo->rcs->path) || !isreadable (tmp)))
{
free(tmp);
return (1);
}
- free(tmp);
+ /* The old value of finfo->rcs->path is in old_path, and is
+ freed below. */
+ finfo->rcs->path = tmp;
}
/* Print message that file was removed. */
- (void) printf ("%s <-- %s\n", rcs, file);
+ (void) printf ("%s <-- %s\n", old_path, finfo->file);
(void) printf ("new revision: delete; ");
(void) printf ("previous revision: %s\n", prev_rev);
(void) printf ("done\n");
free(prev_rev);
- Scratch_Entry (entries, file);
+ if (old_path != finfo->rcs->path)
+ free (old_path);
+
+ Scratch_Entry (finfo->entries, finfo->file);
return (0);
}
@@ -1365,29 +1560,25 @@ remove_file (file, repository, tag, message, entries, rcsnode)
* Do the actual checkin for added files
*/
static int
-finaladd (file, rev, tag, options, update_dir, repository, entries)
- char *file;
+finaladd (finfo, rev, tag, options)
+ struct file_info *finfo;
char *rev;
char *tag;
char *options;
- char *update_dir;
- char *repository;
- List *entries;
{
int ret;
char tmp[PATH_MAX];
char rcs[PATH_MAX];
- locate_rcs (file, repository, rcs);
- ret = Checkin ('A', file, update_dir, repository, rcs, rev, tag, options,
- message, entries);
+ locate_rcs (finfo->file, finfo->repository, rcs);
+ ret = Checkin ('A', finfo, rcs, rev, tag, options, message);
if (ret == 0)
{
- (void) sprintf (tmp, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
+ (void) sprintf (tmp, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
(void) unlink_file (tmp);
}
else
- fixaddfile (file, repository);
+ fixaddfile (finfo->file, finfo->repository);
(void) time (&last_register_time);
@@ -1398,18 +1589,14 @@ finaladd (file, rev, tag, options, update_dir, repository, entries)
* Unlock an rcs file
*/
static void
-unlockrcs (file, repository)
- char *file;
- char *repository;
+unlockrcs (rcs)
+ RCSNode *rcs;
{
- char rcs[PATH_MAX];
- int retcode = 0;
-
- locate_rcs (file, repository, rcs);
+ int retcode;
if ((retcode = RCS_unlock (rcs, NULL, 0)) != 0)
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "could not unlock %s", rcs);
+ "could not unlock %s", rcs->path);
}
/*
@@ -1438,20 +1625,17 @@ fixaddfile (file, repository)
* put the branch back on an rcs file
*/
static void
-fixbranch (file, repository, branch)
- char *file;
- char *repository;
+fixbranch (rcs, branch)
+ RCSNode *rcs;
char *branch;
{
- char rcs[PATH_MAX];
- int retcode = 0;
+ int retcode;
if (branch != NULL && branch[0] != '\0')
{
- locate_rcs (file, repository, rcs);
if ((retcode = RCS_setbranch (rcs, branch)) != 0)
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
- "cannot restore branch to %s for %s", branch, rcs);
+ "cannot restore branch to %s for %s", branch, rcs->path);
}
}
@@ -1474,15 +1658,21 @@ checkaddfile (file, repository, tag, options, rcsnode)
mode_t omask;
int retcode = 0;
int newfile = 0;
+ RCSNode *rcsfile = NULL;
if (tag)
{
- (void) sprintf(rcs, "%s/%s", repository, CVSATTIC);
- omask = umask (cvsumask);
- if (CVS_MKDIR (rcs, 0777) != 0 && errno != EEXIST)
- error (1, errno, "cannot make directory `%s'", rcs);;
- (void) umask (omask);
- (void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
+ (void) sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
+ if (! isreadable (rcs))
+ {
+ (void) sprintf(rcs, "%s/%s", repository, CVSATTIC);
+ omask = umask (cvsumask);
+ if (CVS_MKDIR (rcs, 0777) != 0 && errno != EEXIST)
+ error (1, errno, "cannot make directory `%s'", rcs);;
+ (void) umask (omask);
+ (void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file,
+ RCSEXT);
+ }
}
else
locate_rcs (file, repository, rcs);
@@ -1492,7 +1682,12 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* file has existed in the past. Prepare to resurrect. */
char oldfile[PATH_MAX];
char *rev;
- RCSNode *rcsfile;
+
+ if ((rcsfile = *rcsnode) == NULL)
+ {
+ error (0, 0, "could not find parsed rcsfile %s", file);
+ return (1);
+ }
if (tag == NULL)
{
@@ -1502,7 +1697,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
if (strcmp (oldfile, rcs) == 0
- || rename (oldfile, rcs) != 0
+ || CVS_RENAME (oldfile, rcs) != 0
|| isreadable (oldfile)
|| !isreadable (rcs))
{
@@ -1510,17 +1705,13 @@ checkaddfile (file, repository, tag, options, rcsnode)
file);
return (1);
}
+ free (rcsfile->path);
+ rcsfile->path = xstrdup (rcs);
}
- if ((rcsfile = *rcsnode) == NULL)
- {
- error (0, 0, "could not find parsed rcsfile %s", file);
- return (1);
- }
-
- rev = RCS_getversion (rcsfile, tag, NULL, 1, 0);
+ rev = RCS_getversion (rcsfile, tag, NULL, 1, (int *) NULL);
/* and lock it */
- if (lock_RCS (file, rcs, rev, repository)) {
+ if (lock_RCS (file, rcsfile, rev, repository)) {
error (0, 0, "cannot lock `%s'.", rcs);
free (rev);
return (1);
@@ -1567,7 +1758,7 @@ checkaddfile (file, repository, tag, options, rcsnode)
(void) sprintf (tmp, "file %s was initially added on branch %s.",
file, tag);
retcode = RCS_checkin (rcs, NULL, tmp, NULL,
- RCS_FLAGS_DEAD | RCS_FLAGS_QUIET, 0);
+ RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
free (tmp);
if (retcode != 0)
{
@@ -1578,9 +1769,22 @@ checkaddfile (file, repository, tag, options, rcsnode)
/* put the new file back where it was */
rename_file (fname, file);
-
+
+ assert (rcsfile == NULL);
+ rcsfile = RCS_parse (file, repository);
+ if (rcsfile == NULL)
+ {
+ error (0, 0, "could not read %s", rcs);
+ return (1);
+ }
+ if (rcsnode != NULL)
+ {
+ assert (*rcsnode == NULL);
+ *rcsnode = rcsfile;
+ }
+
/* and lock it once again. */
- if (lock_RCS (file, rcs, NULL, repository)) {
+ if (lock_RCS (file, rcsfile, NULL, repository)) {
error (0, 0, "cannot lock `%s'.", rcs);
return (1);
}
@@ -1590,54 +1794,56 @@ checkaddfile (file, repository, tag, options, rcsnode)
{
/* when adding with a tag, we need to stub a branch, if it
doesn't already exist. */
- RCSNode *rcsfile;
- rcsfile = RCS_parse (file, repository);
if (rcsfile == NULL)
{
- error (0, 0, "could not read %s", rcs);
- return (1);
+ if (rcsnode != NULL && *rcsnode != NULL)
+ rcsfile = *rcsnode;
+ else
+ {
+ rcsfile = RCS_parse (file, repository);
+ if (rcsfile == NULL)
+ {
+ error (0, 0, "could not read %s", rcs);
+ return (1);
+ }
+ }
}
-
+
if (!RCS_nodeisbranch (rcsfile, tag)) {
/* branch does not exist. Stub it. */
char *head;
char *magicrev;
- head = RCS_getversion (rcsfile, NULL, NULL, 0, 0);
+ head = RCS_getversion (rcsfile, NULL, NULL, 0, (int *) NULL);
magicrev = RCS_magicrev (rcsfile, head);
- if ((retcode = RCS_settag(rcs, tag, magicrev)) != 0)
+
+ retcode = RCS_settag (rcsfile, tag, magicrev);
+
+ free (head);
+ free (magicrev);
+
+ if (retcode != 0)
{
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
"could not stub branch %s for %s", tag, rcs);
return (1);
}
-
- freercsnode (&rcsfile);
-
- /* reparse the file, then add it to our list. */
- rcsfile = RCS_parse (file, repository);
- if (rcsfile == NULL)
- {
- error (0, 0, "could not reparse %s", rcs);
- return (1);
- }
-
- free (head);
- free (magicrev);
}
else
{
/* lock the branch. (stubbed branches need not be locked.) */
- if (lock_RCS (file, rcs, NULL, repository)) {
+ if (lock_RCS (file, rcsfile, NULL, repository)) {
error (0, 0, "cannot lock `%s'.", rcs);
return (1);
}
}
- if (rcsnode)
- freercsnode(rcsnode);
- *rcsnode = rcsfile;
+ if (rcsnode && *rcsnode != rcsfile)
+ {
+ freercsnode(rcsnode);
+ *rcsnode = rcsfile;
+ }
}
fileattr_newfile (file);
@@ -1647,24 +1853,6 @@ checkaddfile (file, repository, tag, options, rcsnode)
}
/*
- * Lock the rcs file ``file''
- */
-static int
-lockrcsfile (file, repository, rev)
- char *file;
- char *repository;
- char *rev;
-{
- char rcs[PATH_MAX];
-
- locate_rcs (file, repository, rcs);
- if (lock_RCS (file, rcs, rev, repository) != 0)
- return (1);
- else
- return (0);
-}
-
-/*
* Attempt to place a lock on the RCS file; returns 0 if it could and 1 if it
* couldn't. If the RCS file currently has a branch as the head, we must
* move the head back to the trunk before locking the file, and be sure to
@@ -1673,11 +1861,10 @@ lockrcsfile (file, repository, rev)
static int
lock_RCS (user, rcs, rev, repository)
char *user;
- char *rcs;
+ RCSNode *rcs;
char *rev;
char *repository;
{
- RCSNode *rcsfile;
char *branch = NULL;
int err = 0;
@@ -1692,29 +1879,19 @@ lock_RCS (user, rcs, rev, repository)
*/
if (rev == NULL || (rev && isdigit (*rev) && numdots (rev) < 2))
{
- if ((rcsfile = RCS_parsercsfile (rcs)) == NULL)
- {
- /* invalid rcs file? */
- err = 1;
- }
- else
+ branch = xstrdup (rcs->branch);
+ if (branch != NULL)
{
- /* rcsfile is valid */
- branch = xstrdup (rcsfile->branch);
- freercsnode (&rcsfile);
- if (branch != NULL)
+ if (RCS_setbranch (rcs, NULL) != 0)
{
- if (RCS_setbranch (rcs, NULL) != 0)
- {
- error (0, 0, "cannot change branch to default for %s",
- rcs);
- if (branch)
- free (branch);
- return (1);
- }
+ error (0, 0, "cannot change branch to default for %s",
+ rcs->path);
+ if (branch)
+ free (branch);
+ return (1);
}
- err = RCS_lock(rcs, NULL, 0);
}
+ err = RCS_lock(rcs, NULL, 0);
}
else
{
@@ -1735,7 +1912,7 @@ lock_RCS (user, rcs, rev, repository)
/* try to restore the branch if we can on error */
if (branch != NULL)
- fixbranch (user, repository, branch);
+ fixbranch (rcs, branch);
if (branch)
free (branch);
@@ -1757,18 +1934,23 @@ fix_rcs_modes (rcs, user)
{
struct stat sb;
- if (stat (user, &sb) != -1)
+ if ( CVS_STAT (user, &sb) != -1)
(void) chmod (rcs, (int) sb.st_mode & ~0222);
}
/*
- * free an UPDATE node's data (really nothing to do)
+ * free an UPDATE node's data
*/
void
update_delproc (p)
Node *p;
{
- p->data = (char *) NULL;
+ struct logfile_info *li;
+
+ li = (struct logfile_info *) p->data;
+ if (li->tag)
+ free (li->tag);
+ free (li);
}
/*
diff --git a/gnu/usr.bin/cvs/src/cvs.h b/gnu/usr.bin/cvs/src/cvs.h
index 76b134967ad..c8dbe22f869 100644
--- a/gnu/usr.bin/cvs/src/cvs.h
+++ b/gnu/usr.bin/cvs/src/cvs.h
@@ -76,7 +76,6 @@ extern int errno;
#include "hash.h"
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
-#include "server.h"
#include "client.h"
#endif
@@ -102,12 +101,6 @@ extern int errno;
#endif
#endif /* PATH_MAX */
-/* just in case this implementation does not define this */
-#ifndef L_tmpnam
-#define L_tmpnam 50
-#endif
-
-
/*
* Copyright (c) 1992, Brian Berliner and Jeff Polk
* Copyright (c) 1989-1992, Brian Berliner
@@ -240,12 +233,15 @@ extern int errno;
#define CVSREADONLYFS_ENV "CVSREADONLYFS" /* repository is read-only */
#define RCSBIN_ENV "RCSBIN" /* RCS binary directory */
-/* #define RCSBIN_DFLT Set by config.h */
+/* #define RCSBIN_DFLT Set by options.h */
+
+#define TMPDIR_ENV "TMPDIR" /* Temporary directory */
+/* #define TMPDIR_DFLT Set by options.h */
#define EDITOR1_ENV "CVSEDITOR" /* which editor to use */
#define EDITOR2_ENV "VISUAL" /* which editor to use */
#define EDITOR3_ENV "EDITOR" /* which editor to use */
-/* #define EDITOR_DFLT Set by config.h */
+/* #define EDITOR_DFLT Set by options.h */
#define CVSROOT_ENV "CVSROOT" /* source directory root */
#define CVSROOT_DFLT NULL /* No dflt; must set for checkout */
@@ -254,7 +250,7 @@ extern int errno;
#define WRAPPER_ENV "CVSWRAPPERS" /* name of the wrapper file */
#define CVSUMASK_ENV "CVSUMASK" /* Effective umask for repository */
-/* #define CVSUMASK_DFLT Set by config.h */
+/* #define CVSUMASK_DFLT Set by options.h */
/*
* If the beginning of the Repository matches the following string, strip it
@@ -275,9 +271,16 @@ extern int errno;
#define MAXLISTLEN 40000 /* For [A-Z]list holders */
#define MAXDATELEN 50 /* max length for a date */
+/* The type of an entnode. */
+enum ent_type
+{
+ ENT_FILE, ENT_SUBDIR
+};
+
/* structure of a entry record */
struct entnode
{
+ enum ent_type type;
char *user;
char *version;
char *timestamp;
@@ -295,96 +298,20 @@ enum mtype
};
/*
- * defines for Classify_File() to determine the current state of a file.
- * These are also used as types in the data field for the list we make for
- * Update_Logfile in commit, import, and add.
- */
-enum classify_type
-{
- T_UNKNOWN = 1, /* no old-style analog existed */
- T_CONFLICT, /* C (conflict) list */
- T_NEEDS_MERGE, /* G (needs merging) list */
- T_MODIFIED, /* M (needs checked in) list */
- T_CHECKOUT, /* O (needs checkout) list */
- T_ADDED, /* A (added file) list */
- T_REMOVED, /* R (removed file) list */
- T_REMOVE_ENTRY, /* W (removed entry) list */
- T_UPTODATE, /* File is up-to-date */
-#ifdef SERVER_SUPPORT
- T_PATCH, /* P Like C, but can patch */
-#endif
- T_TITLE /* title for node type */
-};
-typedef enum classify_type Ctype;
-
-/*
- * a struct vers_ts contains all the information about a file including the
- * user and rcs file names, and the version checked out and the head.
- *
- * this is usually obtained from a call to Version_TS which takes a tag argument
- * for the RCS file if desired
- */
-struct vers_ts
-{
- /* rcs version user file derives from, from CVS/Entries.
- * it can have the following special values:
- * empty = no user file
- * 0 = user file is new
- * -vers = user file to be removed. */
- char *vn_user;
-
- /* Numeric revision number corresponding to ->vn_tag (->vn_tag
- will often be symbolic). */
- char *vn_rcs;
- /* If ->tag corresponds to a tag which really exists in this file,
- this is just a copy of ->tag. If not, this is either NULL or
- the head revision. (Or something like that, see RCS_getversion
- and friends). */
- char *vn_tag;
-
- /* This is the timestamp from stating the file in the working directory.
- It is NULL if there is no file in the working directory. */
- char *ts_user;
- /* Timestamp from CVS/Entries. For the server, ts_user and ts_rcs
- are computed in a slightly different way, but the fact remains that
- if they are equal the file in the working directory is unmodified
- and if they differ it is modified. */
- char *ts_rcs;
-
- /* Options from CVS/Entries (keyword expansion). */
- char *options;
-
- /* If non-NULL, there was a conflict (or merely a merge? See merge_file)
- and the time stamp in this field is the time stamp of the working
- directory file which was created with the conflict markers in it.
- This is from CVS/Entries. */
- char *ts_conflict;
-
- /* Tag specified on the command line, or if none, tag stored in
- CVS/Entries. */
- char *tag;
- /* Date specified on the command line, or if none, date stored in
- CVS/Entries. */
- char *date;
-
- /* Pointer to entries file node */
- Entnode *entdata;
-
- /* Pointer to parsed src file info */
- RCSNode *srcfile;
-};
-typedef struct vers_ts Vers_TS;
-
-/*
* structure used for list-private storage by Entries_Open() and
- * Version_TS().
+ * Version_TS() and Find_Directories().
*/
struct stickydirtag
{
+ /* These fields pass sticky tag information from Entries_Open() to
+ Version_TS(). */
int aflag;
char *tag;
char *date;
- char *options;
+ /* This field is set by Entries_Open() if there was subdirectory
+ information; Find_Directories() uses it to see whether it needs
+ to scan the directory itself. */
+ int subdirs;
};
/* Flags for find_{names,dirs} routines */
@@ -400,11 +327,14 @@ enum direnter_type
R_SKIP_DIRS, /* don't process sub-dirs */
R_SKIP_ALL /* don't process files or dirs */
};
+#ifdef ENUMS_CAN_BE_TROUBLE
+typedef int Dtype;
+#else
typedef enum direnter_type Dtype;
+#endif
extern char *program_name, *program_path, *command_name;
-extern char *Rcsbin, *Editor, *CVSroot;
-extern char *CVSADM_Root;
+extern char *Rcsbin, *Tmpdir, *Editor;
extern int cvsadmin_root;
extern char *CurDir;
extern int really_quiet, quiet;
@@ -412,6 +342,20 @@ extern int use_editor;
extern int cvswrite;
extern mode_t cvsumask;
+/* Access method specified in CVSroot. */
+typedef enum {
+ local_method, server_method, pserver_method, kserver_method, ext_method
+} CVSmethod;
+extern char *method_names[]; /* change this in root.c if you change
+ the enum above */
+
+extern char *CVSroot_original; /* the active, complete CVSroot string */
+extern int client_active; /* nonzero if we are doing remote access */
+extern CVSmethod CVSroot_method; /* one of the enum values above */
+extern char *CVSroot_username; /* the username or NULL if method == local */
+extern char *CVSroot_hostname; /* the hostname or NULL if method == local */
+extern char *CVSroot_directory; /* the directory name */
+
extern int trace; /* Show all commands */
extern int noexec; /* Don't modify disk anywhere */
extern int readonlyfs; /* fail on all write locks; succeed all read locks */
@@ -421,24 +365,22 @@ extern char hostname[];
/* Externs that are included directly in the CVS sources */
-int RCS_settag PROTO((const char *, const char *, const char *));
-int RCS_deltag PROTO((const char *, const char *, int));
-int RCS_setbranch PROTO((const char *, const char *));
-int RCS_lock PROTO((const char *, const char *, int));
-int RCS_unlock PROTO((const char *, const char *, int));
+int RCS_exec_settag PROTO((const char *, const char *, const char *));
+int RCS_exec_deltag PROTO((const char *, const char *, int));
+int RCS_exec_setbranch PROTO((const char *, const char *));
+int RCS_exec_lock PROTO((const char *, const char *, int));
+int RCS_exec_unlock PROTO((const char *, const char *, int));
int RCS_merge PROTO((const char *, const char *, const char *, const char *));
-int RCS_checkout PROTO ((char *rcsfile, char *workfile, char *tag,
- char *options,
- char *sout, int flags, int noerr));
+int RCS_exec_checkout PROTO ((char *rcsfile, char *workfile, char *tag,
+ char *options, char *sout));
/* Flags used by RCS_* functions. See the description of the individual
functions for which flags mean what for each function. */
-#define RCS_FLAGS_LOCK 1
-#define RCS_FLAGS_FORCE 2
-#define RCS_FLAGS_DEAD 4
-#define RCS_FLAGS_QUIET 8
-#define RCS_FLAGS_MODTIME 16
+#define RCS_FLAGS_FORCE 1
+#define RCS_FLAGS_DEAD 2
+#define RCS_FLAGS_QUIET 4
+#define RCS_FLAGS_MODTIME 8
int RCS_checkin PROTO ((char *rcsfile, char *workfile, char *message,
- char *rev, int flags, int noerr));
+ char *rev, int flags));
@@ -446,12 +388,17 @@ int RCS_checkin PROTO ((char *rcsfile, char *workfile, char *message,
DBM *open_module PROTO((void));
FILE *open_file PROTO((const char *, const char *));
-List *Find_Directories PROTO((char *repository, int which));
+List *Find_Directories PROTO((char *repository, int which, List *entries));
void Entries_Close PROTO((List *entries));
List *Entries_Open PROTO((int aflag));
+void Subdirs_Known PROTO((List *entries));
+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 *Name_Repository PROTO((char *dir, char *update_dir));
char *Name_Root PROTO((char *dir, char *update_dir));
+int parse_cvsroot PROTO((char *CVSroot));
+void set_local_cvsroot PROTO((char *dir));
void Create_Root PROTO((char *dir, char *rootdir));
int same_directories PROTO((char *dir1, char *dir2));
char *Short_Repository PROTO((char *repository));
@@ -462,8 +409,6 @@ char *xmalloc PROTO((size_t bytes));
void *xrealloc PROTO((void *ptr, size_t bytes));
char *xstrdup PROTO((const char *str));
void strip_trailing_newlines PROTO((char *str));
-int No_Difference PROTO((char *file, Vers_TS * vers, List * entries,
- char *repository, char *update_dir));
typedef int (*CALLPROC) PROTO((char *repository, char *value));
int Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
int Reader_Lock PROTO((char *xrepository));
@@ -479,6 +424,7 @@ int isaccessible PROTO((const char *file, const int mode));
int isabsolute PROTO((const char *filename));
char *last_component PROTO((char *path));
char *get_homedir PROTO ((void));
+char *cvs_temp_name PROTO ((void));
int numdots PROTO((const char *s));
int unlink_file PROTO((const char *f));
@@ -512,7 +458,6 @@ void copy_file PROTO((const char *from, const char *to));
void (*error_set_cleanup PROTO((void (*) (void)))) PROTO ((void));
void fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
void free_names PROTO((int *pargc, char *argv[]));
-void freevers_ts PROTO((Vers_TS ** versp));
extern int ign_name PROTO ((char *name));
void ign_add PROTO((char *ign, int hold));
@@ -521,7 +466,7 @@ void ign_setup PROTO((void));
void ign_dir_add PROTO((char *name));
int ignore_directory PROTO((char *name));
typedef void (*Ignore_proc) PROTO ((char *, char *));
-extern void ignore_files PROTO ((List *, char *, Ignore_proc));
+extern void ignore_files PROTO ((List *, List *, char *, Ignore_proc));
extern int ign_inhibit_server;
extern int ign_case;
@@ -530,6 +475,7 @@ extern int ign_case;
void line2argv PROTO((int *pargc, char *argv[], char *line));
void make_directories PROTO((const char *name));
void make_directory PROTO((const char *name));
+extern int mkdir_if_needed PROTO ((char *name));
void rename_file PROTO((const char *from, const char *to));
/* Expand wildcards in each element of (ARGC,ARGV). This is according to the
files which exist in the current directory, and accordingly to OS-specific
@@ -547,22 +493,12 @@ void update_delproc PROTO((Node * p));
void usage PROTO((const char *const *cpp));
void xchmod PROTO((char *fname, int writable));
char *xgetwd PROTO((void));
-int Checkin PROTO((int type, char *file, char *update_dir,
- char *repository, char *rcs, char *rev,
- char *tag, char *options, char *message, List *entries));
-Ctype Classify_File PROTO((char *file, char *tag, char *date, char *options,
- int force_tag_match, int aflag, char *repository,
- List *entries, RCSNode *rcsnode, Vers_TS **versp,
- char *update_dir, int pipeout));
List *Find_Names PROTO((char *repository, int which, int aflag,
List ** optentries));
void Register PROTO((List * list, char *fname, char *vn, char *ts,
char *options, char *tag, char *date, char *ts_conflict));
-void Update_Logfile PROTO((char *repository, char *xmessage, char *xrevision,
- FILE * xlogfp, List * xchanges));
-Vers_TS *Version_TS PROTO((char *repository, char *options, char *tag,
- char *date, char *user, int force_tag_match,
- int set_time, List * entries, RCSNode * rcs));
+void Update_Logfile PROTO((char *repository, char *xmessage, FILE * xlogfp,
+ List * xchanges));
void do_editor PROTO((char *dir, char **messagep,
char *repository, List * changes));
@@ -599,10 +535,15 @@ struct file_info
RCSNode *rcs;
};
-typedef int (*FILEPROC) PROTO((struct file_info *finfo));
-typedef int (*FILESDONEPROC) PROTO((int err, char *repository, char *update_dir));
-typedef Dtype (*DIRENTPROC) PROTO((char *dir, char *repos, char *update_dir));
-typedef int (*DIRLEAVEPROC) PROTO((char *dir, int err, char *update_dir));
+typedef int (*FILEPROC) PROTO ((void *callerdat, struct file_info *finfo));
+typedef int (*FILESDONEPROC) PROTO ((void *callerdat, int err,
+ char *repository, char *update_dir,
+ List *entries));
+typedef Dtype (*DIRENTPROC) PROTO ((void *callerdat, char *dir,
+ char *repos, char *update_dir,
+ List *entries));
+typedef int (*DIRLEAVEPROC) PROTO ((void *callerdat, char *dir, int err,
+ char *update_dir, List *entries));
extern int mkmodules PROTO ((char *dir));
extern int init PROTO ((int argc, char **argv));
@@ -610,17 +551,14 @@ extern int init PROTO ((int argc, char **argv));
int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
CALLBACKPROC callback_proc, char *where, int shorten,
int local_specified, int run_module_prog, char *extra_arg));
-int do_recursion PROTO((FILEPROC xfileproc, FILESDONEPROC xfilesdoneproc,
- DIRENTPROC xdirentproc, DIRLEAVEPROC xdirleaveproc,
- Dtype xflags, int xwhich, int xaflag, int xreadlock,
- int xdosrcs));
void history_write PROTO((int type, char *update_dir, char *revs, char *name,
char *repository));
int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
DIRENTPROC direntproc, DIRLEAVEPROC dirleaveproc,
+ void *callerdat,
int argc, char *argv[], int local, int which,
int aflag, int readlock, char *update_preload,
- int dosrcs, int wd_is_repos));
+ int dosrcs));
void SIG_beginCrSect PROTO((void));
void SIG_endCrSect PROTO((void));
void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
@@ -655,18 +593,133 @@ int filter_stream_through_program PROTO((int, int, char **, pid_t *));
pid_t waitpid PROTO((pid_t, int *, int));
+/*
+ * a struct vers_ts contains all the information about a file including the
+ * user and rcs file names, and the version checked out and the head.
+ *
+ * this is usually obtained from a call to Version_TS which takes a
+ * tag argument for the RCS file if desired
+ */
+struct vers_ts
+{
+ /* rcs version user file derives from, from CVS/Entries.
+ * it can have the following special values:
+ * empty = no user file
+ * 0 = user file is new
+ * -vers = user file to be removed. */
+ char *vn_user;
+
+ /* Numeric revision number corresponding to ->vn_tag (->vn_tag
+ will often be symbolic). */
+ char *vn_rcs;
+ /* If ->tag is a simple tag in the RCS file--a tag which really
+ exists which is not a magic revision--and if ->date is NULL,
+ then this is a copy of ->tag. Otherwise, it is a copy of
+ ->vn_rcs. */
+ char *vn_tag;
+
+ /* This is the timestamp from stating the file in the working directory.
+ It is NULL if there is no file in the working directory. */
+ char *ts_user;
+ /* Timestamp from CVS/Entries. For the server, ts_user and ts_rcs
+ are computed in a slightly different way, but the fact remains that
+ if they are equal the file in the working directory is unmodified
+ and if they differ it is modified. */
+ char *ts_rcs;
+
+ /* Options from CVS/Entries (keyword expansion). */
+ char *options;
+
+ /* If non-NULL, there was a conflict (or merely a merge? See merge_file)
+ and the time stamp in this field is the time stamp of the working
+ directory file which was created with the conflict markers in it.
+ This is from CVS/Entries. */
+ char *ts_conflict;
+
+ /* Tag specified on the command line, or if none, tag stored in
+ CVS/Entries. */
+ char *tag;
+ /* Date specified on the command line, or if none, date stored in
+ CVS/Entries. */
+ char *date;
+
+ /* Pointer to entries file node */
+ Entnode *entdata;
+
+ /* Pointer to parsed src file info */
+ RCSNode *srcfile;
+};
+typedef struct vers_ts Vers_TS;
+
+Vers_TS *Version_TS PROTO ((struct file_info *finfo, char *options, char *tag,
+ char *date, int force_tag_match,
+ int set_time));
+void freevers_ts PROTO ((Vers_TS ** versp));
+
+/* Miscellaneous CVS infrastructure which layers on top of the recursion
+ processor (for example, needs struct file_info). */
+
+int Checkin PROTO ((int type, struct file_info *finfo, char *rcs, char *rev,
+ char *tag, char *options, char *message));
+int No_Difference PROTO ((struct file_info *finfo, Vers_TS *vers));
+
+/*
+ * defines for Classify_File() to determine the current state of a file.
+ * These are also used as types in the data field for the list we make for
+ * Update_Logfile in commit, import, and add.
+ */
+enum classify_type
+{
+ T_UNKNOWN = 1, /* no old-style analog existed */
+ T_CONFLICT, /* C (conflict) list */
+ T_NEEDS_MERGE, /* G (needs merging) list */
+ T_MODIFIED, /* M (needs checked in) list */
+ T_CHECKOUT, /* O (needs checkout) list */
+ T_ADDED, /* A (added file) list */
+ T_REMOVED, /* R (removed file) list */
+ T_REMOVE_ENTRY, /* W (removed entry) list */
+ T_UPTODATE, /* File is up-to-date */
+#ifdef SERVER_SUPPORT
+ T_PATCH, /* P Like C, but can patch */
+#endif
+ T_TITLE /* title for node type */
+};
+typedef enum classify_type Ctype;
+
+Ctype Classify_File PROTO
+ ((struct file_info *finfo, char *tag, char *date, char *options,
+ int force_tag_match, int aflag, Vers_TS **versp, int pipeout));
+
+/*
+ * structure used for list nodes passed to Update_Logfile() and
+ * do_editor().
+ */
+struct logfile_info
+{
+ enum classify_type type;
+ char *tag;
+};
+
/* Wrappers. */
typedef enum { WRAP_MERGE, WRAP_COPY } WrapMergeMethod;
-typedef enum { WRAP_TOCVS, WRAP_FROMCVS, WRAP_CONFLICT } WrapMergeHas;
+typedef enum {
+ /* -t and -f wrapper options. Treating directories as single files. */
+ WRAP_TOCVS,
+ WRAP_FROMCVS,
+ /* -k wrapper option. Default keyword expansion options. */
+ WRAP_RCSOPTION
+} WrapMergeHas;
void wrap_setup PROTO((void));
int wrap_name_has PROTO((const char *name,WrapMergeHas has));
+char *wrap_rcsoption PROTO ((const char *fileName, int asFlag));
char *wrap_tocvs_process_file PROTO((const char *fileName));
int wrap_merge_is_copy PROTO((const char *fileName));
char *wrap_fromcvs_process_file PROTO((const char *fileName));
void wrap_add_file PROTO((const char *file,int temp));
void wrap_add PROTO((char *line,int temp));
+void wrap_send PROTO ((void));
/* Pathname expansion */
char *expand_path PROTO((char *name, char *file, int line));
@@ -688,7 +741,20 @@ char *scramble PROTO ((char *str));
char *descramble PROTO ((char *str));
#endif /* AUTH_CLIENT_SUPPORT || AUTH_SERVER_SUPPORT */
+#ifdef AUTH_CLIENT_SUPPORT
+char *get_cvs_password PROTO((void));
+#endif /* AUTH_CLIENT_SUPPORT */
+
extern void tag_check_valid PROTO ((char *, int, char **, int, int, char *));
+extern void tag_check_valid_join PROTO ((char *, int, char **, int, int,
+ char *));
+extern void tag_lockdir PROTO ((char *));
+extern void tag_unlockdir PROTO ((void));
+
+extern void cvs_output PROTO ((const char *, size_t));
+extern void cvs_outerr PROTO ((const char *, size_t));
+extern void cvs_flusherr PROTO ((void));
-extern void cvs_output PROTO ((char *, size_t));
-extern void cvs_outerr PROTO ((char *, size_t));
+#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
+#include "server.h"
+#endif
diff --git a/gnu/usr.bin/cvs/src/ignore.c b/gnu/usr.bin/cvs/src/ignore.c
index 7d947cb8941..36d46cdfa6c 100644
--- a/gnu/usr.bin/cvs/src/ignore.c
+++ b/gnu/usr.bin/cvs/src/ignore.c
@@ -20,7 +20,7 @@ static int s_ign_count = 0;
static int ign_size; /* This many slots available (plus
* one for a NULL) */
static int ign_hold = -1; /* Index where first "temporary" item
- * is held, -1 if none. */
+ * is held */
const char *ign_default = ". .. core RCSLOG tags TAGS RCS SCCS .make.state\
.nse_depinfo #* .#* cvslog.* ,* CVS CVS.adm .del-* *.a *.olb *.o *.obj\
@@ -42,7 +42,7 @@ int ign_inhibit_server;
void
ign_setup ()
{
- struct passwd *pw;
+ char *home_dir;
char file[PATH_MAX];
char *tmp;
@@ -62,15 +62,16 @@ ign_setup ()
#endif
{
/* Then add entries found in repository, if it exists */
- (void) sprintf (file, "%s/%s/%s", CVSroot, CVSROOTADM,
- CVSROOTADM_IGNORE);
+ (void) sprintf (file, "%s/%s/%s", CVSroot_directory,
+ CVSROOTADM, CVSROOTADM_IGNORE);
ign_add_file (file, 0);
}
/* Then add entries found in home dir, (if user has one) and file exists */
- if ((pw = (struct passwd *) getpwuid (getuid ())) && pw->pw_dir)
+ home_dir = get_homedir ();
+ if (home_dir)
{
- (void) sprintf (file, "%s/%s", pw->pw_dir, CVSDOTIGNORE);
+ (void) sprintf (file, "%s/%s", home_dir, CVSDOTIGNORE);
ign_add_file (file, 0);
}
@@ -128,7 +129,7 @@ ign_add_file (file, hold)
}
/* load the file */
- fp = fopen (file, "r");
+ fp = CVS_FOPEN (file, "r");
if (fp == NULL)
{
if (! existence_error (errno))
@@ -327,29 +328,45 @@ int ignore_directory (name)
}
/*
- * Process the current directory, looking for files not in ILIST and not on
- * the global ignore list for this directory. If we find one, call PROC
- * passing it the name of the file and the update dir.
+ * Process the current directory, looking for files not in ILIST and
+ * not on the global ignore list for this directory. If we find one,
+ * call PROC passing it the name of the file and the update dir.
+ * ENTRIES is the entries list, which is used to identify known
+ * directories. ENTRIES may be NULL, in which case we assume that any
+ * directory with a CVS administration directory is known.
*/
void
-ignore_files (ilist, update_dir, proc)
+ignore_files (ilist, entries, update_dir, proc)
List *ilist;
+ List *entries;
char *update_dir;
Ignore_proc proc;
{
+ int subdirs;
DIR *dirp;
struct dirent *dp;
struct stat sb;
char *file;
char *xdir;
+ /* Set SUBDIRS if we have subdirectory information in ENTRIES. */
+ if (entries == NULL)
+ subdirs = 0;
+ else
+ {
+ struct stickydirtag *sdtp;
+
+ sdtp = (struct stickydirtag *) entries->list->data;
+ subdirs = sdtp == NULL || sdtp->subdirs;
+ }
+
/* we get called with update_dir set to "." sometimes... strip it */
if (strcmp (update_dir, ".") == 0)
xdir = "";
else
xdir = update_dir;
- dirp = opendir (".");
+ dirp = CVS_OPENDIR (".");
if (dirp == NULL)
return;
@@ -363,6 +380,34 @@ ignore_files (ilist, update_dir, proc)
continue;
if (findnode_fn (ilist, file) != NULL)
continue;
+ if (subdirs)
+ {
+ Node *node;
+
+ node = findnode_fn (entries, file);
+ if (node != NULL
+ && ((Entnode *) node->data)->type == ENT_SUBDIR)
+ {
+ char *p;
+ int dir;
+
+ /* For consistency with past behaviour, we only ignore
+ this directory if there is a CVS subdirectory.
+ This will normally be the case, but the user may
+ have messed up the working directory somehow. */
+ p = xmalloc (strlen (file) + sizeof CVSADM + 10);
+ sprintf (p, "%s/%s", file, CVSADM);
+ dir = isdir (p);
+ free (p);
+ if (dir)
+ continue;
+ }
+ }
+
+ /* We could be ignoring FIFOs and other files which are neither
+ regular files nor directories here. */
+ if (ign_name (file))
+ continue;
if (
#ifdef DT_DIR
@@ -377,11 +422,14 @@ ignore_files (ilist, update_dir, proc)
#endif
S_ISDIR(sb.st_mode))
{
- char temp[PATH_MAX];
+ if (! subdirs)
+ {
+ char temp[PATH_MAX];
- (void) sprintf (temp, "%s/%s", file, CVSADM);
- if (isdir (temp))
- continue;
+ (void) sprintf (temp, "%s/%s", file, CVSADM);
+ if (isdir (temp))
+ continue;
+ }
}
#ifdef S_ISLNK
else if (
@@ -395,10 +443,6 @@ ignore_files (ilist, update_dir, proc)
#endif
}
- /* We could be ignoring FIFOs and other files which are neither
- regular files nor directories here. */
- if (ign_name (file))
- continue;
(*proc) (file, xdir);
}
(void) closedir (dirp);
diff --git a/gnu/usr.bin/cvs/src/lock.c b/gnu/usr.bin/cvs/src/lock.c
index 5e1d22e2de9..81179bde66c 100644
--- a/gnu/usr.bin/cvs/src/lock.c
+++ b/gnu/usr.bin/cvs/src/lock.c
@@ -10,6 +10,68 @@
* Lock file support for CVS.
*/
+/* The node Concurrency in doc/cvs.texinfo has a brief introduction to
+ how CVS locks function, and some of the user-visible consequences of
+ their existence. Here is a summary of why they exist (and therefore,
+ the consequences of hacking CVS to read a repository without creating
+ locks):
+
+ There are two uses. One is the ability to prevent there from being
+ two writers at the same time. This is necessary for any number of
+ reasons (fileattr code, probably others). Commit needs to lock the
+ whole tree so that nothing happens between the up-to-date check and
+ the actual checkin.
+
+ The second use is the ability to ensure that there is not a writer
+ and a reader at the same time (several readers are allowed). Reasons
+ for this are:
+
+ * Readlocks ensure that once CVS has found a collection of rcs
+ files using Find_Names, the files will still exist when it reads
+ them (they may have moved in or out of the attic).
+
+ * Readlocks provide some modicum of consistency, although this is
+ kind of limited--see the node Concurrency in cvs.texinfo.
+
+ * Readlocks ensure that the RCS file does not change between
+ RCS_parse and RCS_reparsercsfile time. This one strikes me as
+ important, although I haven't thought up what bad scenarios might
+ be.
+
+ * Readlocks ensure that we won't find the file in the state in
+ which it is in between the "rcs -i" and the RCS_checkin in commit.c
+ (when a file is being added). This state is a state in which the
+ RCS file parsing routines in rcs.c cannot parse the file.
+
+ * Readlocks ensure that a reader won't try to look at a
+ half-written fileattr file (fileattr is not updated atomically).
+
+ (see also the description of anonymous read-only access in
+ "Password authentication security" node in doc/cvs.texinfo).
+
+ While I'm here, I'll try to summarize a few random suggestions
+ which periodically get made about how locks might be different:
+
+ 1. Check for EROFS. Maybe useful, although in the presence of NFS
+ EROFS does *not* mean that the file system is unchanging.
+
+ 2. Provide a means to put the cvs locks in some directory apart from
+ the repository (CVSROOT/locks; a -l option in modules; etc.).
+
+ 3. Provide an option to disable locks for operations which only
+ read (see above for some of the consequences).
+
+ 4. Have a server internally do the locking. Probably a good
+ long-term solution, and many people have been working hard on code
+ changes which would eventually make it possible to have a server
+ which can handle various connections in one process, but there is
+ much, much work still to be done before this is feasible.
+
+ 5. Like #4 but use shared memory or something so that the servers
+ merely need to all be on the same machine. This is a much smaller
+ change to CVS (it functions much like #2; shared memory might be an
+ unneeded complication although it presumably would be faster). */
+
#include "cvs.h"
static int readers_exist PROTO((char *repository));
@@ -21,6 +83,7 @@ static int unlock_proc PROTO((Node * p, void *closure));
static int write_lock PROTO((char *repository));
static void lock_simple_remove PROTO((char *repository));
static void lock_wait PROTO((char *repository));
+static void lock_obtained PROTO((char *repository));
static int Check_Owner PROTO((char *lockdir));
static char lockers_name[20];
@@ -78,14 +141,14 @@ lock_simple_remove (repository)
if (readlock[0] != '\0')
{
(void) sprintf (tmp, "%s/%s", repository, readlock);
- if (unlink (tmp) < 0 && ! existence_error (errno))
+ if ( CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
error (0, errno, "failed to remove lock %s", tmp);
}
if (writelock[0] != '\0')
{
(void) sprintf (tmp, "%s/%s", repository, writelock);
- if (unlink (tmp) < 0 && ! existence_error (errno))
+ if ( CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
error (0, errno, "failed to remove lock %s", tmp);
}
@@ -104,7 +167,7 @@ lock_simple_remove (repository)
sprintf(rmuidlock, "rm -f %s/uidlock%d", tmp, geteuid() );
system(rmuidlock);
#endif
- (void) rmdir (tmp);
+ (void) CVS_RMDIR (tmp);
}
}
cleanup_lckdir = 0;
@@ -134,7 +197,7 @@ Check_Owner(lockdir)
* Assume that we don't own it.
*/
#else
- if (stat (lockdir, &sb) != -1 && sb.st_uid == geteuid ())
+ if ( CVS_STAT (lockdir, &sb) != -1 && sb.st_uid == geteuid ())
return 1;
else
return 0;
@@ -186,7 +249,7 @@ Reader_Lock (xrepository)
/* write a read-lock */
(void) sprintf (tmp, "%s/%s", xrepository, readlock);
- if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
+ if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF)
{
error (0, errno, "cannot create read lock in repository `%s'",
xrepository);
@@ -209,6 +272,8 @@ int
Writer_Lock (list)
List *list;
{
+ char *wait_repos;
+
if (noexec)
return (0);
@@ -219,6 +284,7 @@ Writer_Lock (list)
return (1);
}
+ wait_repos = NULL;
for (;;)
{
/* try to lock everything on the list */
@@ -232,6 +298,8 @@ Writer_Lock (list)
switch (lock_error)
{
case L_ERROR: /* Real Error */
+ if (wait_repos != NULL)
+ free (wait_repos);
Lock_Cleanup (); /* clean up any locks we set */
error (0, 0, "lock failed - giving up");
return (1);
@@ -239,12 +307,20 @@ Writer_Lock (list)
case L_LOCKED: /* Someone already had a lock */
Lock_Cleanup (); /* clean up any locks we set */
lock_wait (lock_error_repos); /* sleep a while and try again */
+ wait_repos = xstrdup (lock_error_repos);
continue;
case L_OK: /* we got the locks set */
+ if (wait_repos != NULL)
+ {
+ lock_obtained (wait_repos);
+ free (wait_repos);
+ }
return (0);
default:
+ if (wait_repos != NULL)
+ free (wait_repos);
error (0, 0, "unknown lock status %d in Writer_Lock",
lock_error);
return (1);
@@ -310,11 +386,11 @@ write_lock (repository)
/* write the write-lock file */
(void) sprintf (tmp, "%s/%s", repository, writelock);
- if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
+ if ((fp = CVS_FOPEN (tmp, "w+")) == NULL || fclose (fp) == EOF)
{
int xerrno = errno;
- if (unlink (tmp) < 0 && ! existence_error (errno))
+ if ( CVS_UNLINK (tmp) < 0 && ! existence_error (errno))
error (0, errno, "failed to remove lock %s", tmp);
/* free the lock dir if we created it */
@@ -353,7 +429,7 @@ readers_exist (repository)
again:
#endif
- if ((dirp = opendir (repository)) == NULL)
+ if ((dirp = CVS_OPENDIR (repository)) == NULL)
error (1, 0, "cannot open directory %s", repository);
errno = 0;
@@ -368,7 +444,7 @@ again:
line = xmalloc (strlen (repository) + strlen (dp->d_name) + 5);
(void) sprintf (line, "%s/%s", repository, dp->d_name);
- if (stat (line, &sb) != -1)
+ if ( CVS_STAT (line, &sb) != -1)
{
#ifdef CVS_FUDGELOCKS
/*
@@ -376,7 +452,7 @@ again:
* seconds ago, try to clean-up the lock file, and if
* successful, re-open the directory and try again.
*/
- if (now >= (sb.st_ctime + CVSLCKAGE) && unlink (line) != -1)
+ if (now >= (sb.st_ctime + CVSLCKAGE) && CVS_UNLINK (line) != -1)
{
(void) closedir (dirp);
free (line);
@@ -437,6 +513,7 @@ set_lock (repository, will_wait)
char *repository;
int will_wait;
{
+ int waited;
struct stat sb;
mode_t omask;
#ifdef CVS_FUDGELOCKS
@@ -450,6 +527,7 @@ set_lock (repository, will_wait)
* handlers that do the appropriate things, like remove the lock
* directory before they exit.
*/
+ waited = 0;
cleanup_lckdir = 0;
for (;;)
{
@@ -463,11 +541,11 @@ set_lock (repository, will_wait)
FILE *fp;
sprintf(uidlock, "%s/uidlock%d", masterlock, geteuid() );
- if ((fp = fopen(uidlock, "w+")) == NULL)
+ if ((fp = CVS_FOPEN (uidlock, "w+")) == NULL)
{
/* We failed to create the uidlock,
so rm masterlock and leave */
- rmdir(masterlock);
+ CVS_RMDIR (masterlock);
SIG_endCrSect ();
status = L_ERROR;
goto out;
@@ -479,6 +557,8 @@ set_lock (repository, will_wait)
cleanup_lckdir = 1;
SIG_endCrSect ();
status = L_OK;
+ if (waited)
+ lock_obtained (repository);
goto out;
}
SIG_endCrSect ();
@@ -495,11 +575,10 @@ set_lock (repository, will_wait)
return (L_ERROR);
}
- /*
- * stat the dir - if it is non-existent, re-try the loop since
- * someone probably just removed it (thus releasing the lock)
- */
- if (stat (masterlock, &sb) < 0)
+ /* Find out who owns the lock. If the lock directory is
+ non-existent, re-try the loop since someone probably just
+ removed it (thus releasing the lock). */
+ if (CVS_STAT (masterlock, &sb) < 0)
{
if (existence_error (errno))
continue;
@@ -523,7 +602,7 @@ set_lock (repository, will_wait)
sprintf(rmuidlock, "rm -f %s/uidlock%d", masterlock, geteuid() );
system(rmuidlock);
#endif
- if (rmdir (masterlock) >= 0)
+ if (CVS_RMDIR (masterlock) >= 0)
continue;
}
#endif
@@ -535,6 +614,7 @@ set_lock (repository, will_wait)
if (!will_wait)
return (L_LOCKED);
lock_wait (repository);
+ waited = 1;
}
}
@@ -551,7 +631,7 @@ clear_lock()
sprintf(rmuidlock, "rm -f %s/uidlock%d", masterlock, geteuid() );
system(rmuidlock);
#endif
- if (rmdir (masterlock) < 0)
+ if (CVS_RMDIR (masterlock) < 0)
error (0, errno, "failed to remove lock dir `%s'", masterlock);
cleanup_lckdir = 0;
}
@@ -568,11 +648,31 @@ lock_wait (repos)
(void) time (&now);
error (0, 0, "[%8.8s] waiting for %s's lock in %s", ctime (&now) + 11,
lockers_name, repos);
+ /* Call cvs_flusherr to ensure that the user sees this message as
+ soon as possible. */
+ cvs_flusherr ();
(void) sleep (CVSLCKSLEEP);
}
+
+/*
+ * Print out a message when we obtain a lock.
+ */
+static void
+lock_obtained (repos)
+ char *repos;
+{
+ time_t now;
+
+ (void) time (&now);
+ error (0, 0, "[%8.8s] obtained lock in %s", ctime (&now) + 11, repos);
+ /* Call cvs_flusherr to ensure that the user sees this message as
+ soon as possible. */
+ cvs_flusherr ();
+}
-static int lock_filesdoneproc PROTO ((int err, char *repository,
- char *update_dir));
+static int lock_filesdoneproc PROTO ((void *callerdat, int err,
+ char *repository, char *update_dir,
+ List *entries));
static int fsortcmp PROTO((const Node * p, const Node * q));
static List *lock_tree_list;
@@ -582,10 +682,12 @@ static List *lock_tree_list;
*/
/* ARGSUSED */
static int
-lock_filesdoneproc (err, repository, update_dir)
+lock_filesdoneproc (callerdat, err, repository, update_dir, entries)
+ void *callerdat;
int err;
char *repository;
char *update_dir;
+ List *entries;
{
Node *p;
@@ -623,9 +725,8 @@ lock_tree_for_write (argc, argv, local, aflag)
*/
lock_tree_list = getlist ();
err = start_recursion ((FILEPROC) NULL, lock_filesdoneproc,
- (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, argc,
- argv, local, W_LOCAL, aflag, 0, (char *) NULL, 0,
- 0);
+ (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, argc,
+ argv, local, W_LOCAL, aflag, 0, (char *) NULL, 0);
sortlist (lock_tree_list, fsortcmp);
if (Writer_Lock (lock_tree_list) != 0)
error (1, 0, "lock failed - giving up");
diff --git a/gnu/usr.bin/cvs/src/main.c b/gnu/usr.bin/cvs/src/main.c
index bf9c83c1b38..5e1f000a690 100644
--- a/gnu/usr.bin/cvs/src/main.c
+++ b/gnu/usr.bin/cvs/src/main.c
@@ -10,27 +10,6 @@
* Credit to Dick Grune, Vrije Universiteit, Amsterdam, for writing
* the shell-script CVS system that this is based on.
*
- * Usage:
- * cvs [options] command [options] [files/modules...]
- *
- * Where "command" is composed of:
- * admin RCS command
- * checkout Check out a module/dir/file
- * export Like checkout, but used for exporting sources
- * update Brings work tree in sync with repository
- * commit Checks files into the repository
- * diff Runs diffs between revisions
- * log Prints "rlog" information for files
- * login Record user, host, repos, password
- * add Adds an entry to the repository
- * remove Removes an entry from the repository
- * status Status info on the revisions
- * rdiff "patch" format diff listing between releases
- * tag Add/delete a symbolic tag to the RCS file
- * rtag Add/delete a symbolic tag to the RCS file
- * import Import sources into CVS, using vendor branches
- * release Indicate that Module is no longer in use.
- * history Display history of Users and Modules.
*/
#include "cvs.h"
@@ -41,22 +20,9 @@
extern int gethostname ();
#endif
-#if HAVE_KERBEROS
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <krb.h>
-#ifndef HAVE_KRB_GET_ERR_TEXT
-#define krb_get_err_text(status) krb_err_txt[status]
-#endif
-#endif
-
char *program_name;
char *program_path;
-/*
- * Initialize comamnd_name to "cvs" so that the first call to
- * read_cvsrc tries to find global cvs options.
- */
-char *command_name = "";
+char *command_name;
/*
* Since some systems don't define this...
@@ -67,9 +33,6 @@ char *command_name = "";
char hostname[MAXHOSTNAMELEN];
-#ifdef AUTH_CLIENT_SUPPORT
-int use_authenticating_server = FALSE;
-#endif /* AUTH_CLIENT_SUPPORT */
int use_editor = TRUE;
int use_cvsrc = TRUE;
int cvswrite = !CVSREAD_DFLT;
@@ -87,13 +50,11 @@ char *CurDir;
* Defaults, for the environment variables that are not set
*/
char *Rcsbin = RCSBIN_DFLT;
+char *Tmpdir = TMPDIR_DFLT;
char *Editor = EDITOR_DFLT;
-char *CVSroot = CVSROOT_DFLT;
/*
* The path found in CVS/Root must match $CVSROOT and/or 'cvs -d root'
*/
-char *CVSADM_Root = CVSROOT_DFLT;
-
int add PROTO((int argc, char **argv));
int admin PROTO((int argc, char **argv));
int checkout PROTO((int argc, char **argv));
@@ -113,61 +74,73 @@ int status PROTO((int argc, char **argv));
int tag PROTO((int argc, char **argv));
int update PROTO((int argc, char **argv));
-const struct cmd
+static const struct cmd
{
char *fullname; /* Full name of the function (e.g. "commit") */
- char *nick1; /* alternate name (e.g. "ci") */
- char *nick2; /* another alternate names (e.g. "ci") */
+
+ /* Synonyms for the command, nick1 and nick2. We supply them
+ mostly for two reasons: (1) CVS has always supported them, and
+ we need to maintain compatibility, (2) if there is a need for a
+ version which is shorter than the fullname, for ease in typing.
+ Synonyms have the disadvantage that people will see "new" and
+ then have to think about it, or look it up, to realize that is
+ the operation they know as "add". Also, this means that one
+ cannot create a command "cvs new" with a different meaning. So
+ new synonyms are probably best used sparingly, and where used
+ should be abbreviations of the fullname (preferably consisting
+ of the first 2 or 3 or so letters).
+
+ One thing that some systems do is to recognize any unique
+ abbreviation, for example "annotat" "annota", etc., for
+ "annotate". The problem with this is that scripts and user
+ habits will expect a certain abbreviation to be unique, and in
+ a future release of CVS it may not be. So it is better to
+ accept only an explicit list of abbreviations and plan on
+ supporting them in the future as well as now. */
+
+ char *nick1;
+ char *nick2;
+
int (*func) (); /* Function takes (argc, argv) arguments. */
-#ifdef CLIENT_SUPPORT
- int (*client_func) (); /* Function to do it via the protocol. */
-#endif
} cmds[] =
{
-#ifdef CLIENT_SUPPORT
-#define CMD_ENTRY(n1, n2, n3, f1, f2) { n1, n2, n3, f1, f2 }
-#else
-#define CMD_ENTRY(n1, n2, n3, f1, f2) { n1, n2, n3, f1 }
+ { "add", "ad", "new", add },
+ { "admin", "adm", "rcs", admin },
+ { "annotate", "ann", NULL, annotate },
+ { "checkout", "co", "get", checkout },
+ { "commit", "ci", "com", commit },
+ { "diff", "di", "dif", diff },
+ { "edit", NULL, NULL, edit },
+ { "editors", NULL, NULL, editors },
+ { "export", "exp", "ex", checkout },
+ { "history", "hi", "his", history },
+ { "import", "im", "imp", import },
+ { "init", NULL, NULL, init },
+#ifdef SERVER_SUPPORT
+ { "kserver", NULL, NULL, server }, /* placeholder */
#endif
-
- CMD_ENTRY("add", "ad", "new", add, client_add),
- CMD_ENTRY("admin", "adm", "rcs", admin, client_admin),
- CMD_ENTRY("annotate", NULL, NULL, annotate, client_annotate),
- CMD_ENTRY("checkout", "co", "get", checkout, client_checkout),
- CMD_ENTRY("commit", "ci", "com", commit, client_commit),
- CMD_ENTRY("diff", "di", "dif", diff, client_diff),
- CMD_ENTRY("edit", "edit", "edit", edit, client_edit),
- CMD_ENTRY("editors", "editors","editors",editors, client_editors),
- CMD_ENTRY("export", "exp", "ex", checkout, client_export),
- CMD_ENTRY("history", "hi", "his", history, client_history),
- CMD_ENTRY("import", "im", "imp", import, client_import),
- CMD_ENTRY("init", NULL, NULL, init, client_init),
- CMD_ENTRY("log", "lo", "rlog", cvslog, client_log),
+ { "log", "lo", "rlog", cvslog },
#ifdef AUTH_CLIENT_SUPPORT
- CMD_ENTRY("login", "logon", "lgn", login, login),
+ { "login", "logon", "lgn", login },
+#ifdef SERVER_SUPPORT
+ { "pserver", NULL, NULL, server }, /* placeholder */
+#endif
#endif /* AUTH_CLIENT_SUPPORT */
- CMD_ENTRY("rdiff", "patch", "pa", patch, client_rdiff),
- CMD_ENTRY("release", "re", "rel", release, client_release),
- CMD_ENTRY("remove", "rm", "delete", cvsremove, client_remove),
- CMD_ENTRY("status", "st", "stat", status, client_status),
- CMD_ENTRY("rtag", "rt", "rfreeze", rtag, client_rtag),
- CMD_ENTRY("tag", "ta", "freeze", tag, client_tag),
- CMD_ENTRY("unedit", "unedit","unedit", unedit, client_unedit),
- CMD_ENTRY("update", "up", "upd", update, client_update),
- CMD_ENTRY("watch", "watch", "watch", watch, client_watch),
- CMD_ENTRY("watchers", "watchers","watchers",watchers,client_watchers),
+ { "rdiff", "patch", "pa", patch },
+ { "release", "re", "rel", release },
+ { "remove", "rm", "delete", cvsremove },
+ { "status", "st", "stat", status },
+ { "rtag", "rt", "rfreeze", rtag },
+ { "tag", "ta", "freeze", tag },
+ { "unedit", NULL, NULL, unedit },
+ { "update", "up", "upd", update },
+ { "watch", NULL, NULL, watch },
+ { "watchers", NULL, NULL, watchers },
#ifdef SERVER_SUPPORT
- /*
- * The client_func is also server because we might have picked up a
- * CVSROOT environment variable containing a colon. The client will send
- * the real root later.
- */
- CMD_ENTRY("server", "server", "server", server, server),
+ { "server", NULL, NULL, server },
#endif
- CMD_ENTRY(NULL, NULL, NULL, NULL, NULL),
-
-#undef CMD_ENTRY
+ { NULL, NULL, NULL, NULL },
};
static const char *const usg[] =
@@ -184,11 +157,15 @@ static const char *const usg[] =
" -t Show trace of program execution -- Try with -n\n",
" -v CVS version and copyright\n",
" -b bindir Find RCS programs in 'bindir'\n",
+ " -T tmpdir Use 'tmpdir' for temporary files\n",
" -e editor Use 'editor' for editing log information\n",
" -d CVS_root Overrides $CVSROOT as the root of the CVS tree\n",
" -f Do not use the ~/.cvsrc file\n",
#ifdef CLIENT_SUPPORT
- " -z # Use 'gzip -#' for net traffic if possible.\n",
+ " -z # Use compression level '#' for net traffic.\n",
+#ifdef ENCRYPTION
+ " -x Encrypt all net traffic.\n",
+#endif
#endif
" -s VAR=VAL Set CVS user variable.\n",
"\n",
@@ -200,60 +177,114 @@ static const char *const usg[] =
static const char *const cmd_usage[] =
{
"CVS commands are:\n",
- " add Adds a new file/directory to the repository\n",
+ " add Add a new file/directory to the repository\n",
" admin Administration front end for rcs\n",
- " annotate Show revision where each line was modified\n",
+ " annotate Show last revision where each line was modified\n",
" checkout Checkout sources for editing\n",
- " commit Checks files into the repository\n",
- " diff Runs diffs between revisions\n",
+ " commit Check files into the repository\n",
+ " diff Run diffs between revisions\n",
" edit Get ready to edit a watched file\n",
" editors See who is editing a watched file\n",
- " history Shows status of files and users\n",
- " import Import sources into CVS, using vendor branches\n",
" export Export sources from CVS, similar to checkout\n",
- " log Prints out 'rlog' information for files\n",
+ " history Show repository access history\n",
+ " import Import sources into CVS, using vendor branches\n",
+ " init Create a CVS repository if it doesn't exist\n",
+ " log Print out history information for files\n",
#ifdef AUTH_CLIENT_SUPPORT
" login Prompt for password for authenticating server.\n",
#endif /* AUTH_CLIENT_SUPPORT */
- " rdiff 'patch' format diffs between releases\n",
+ " rdiff Create 'patch' format diffs between releases\n",
" release Indicate that a Module is no longer in use\n",
- " remove Removes an entry from the repository\n",
- " status Status info on the revisions\n",
- " tag Add a symbolic tag to checked out version of RCS file\n",
+ " remove Remove an entry from the repository\n",
+ " rtag Add a symbolic tag to a module\n",
+ " status Display status information on checked out files\n",
+ " tag Add a symbolic tag to checked out version of files\n",
" unedit Undo an edit command\n",
- " rtag Add a symbolic tag to the RCS file\n",
- " update Brings work tree in sync with repository\n",
+ " update Bring work tree in sync with repository\n",
" watch Set watches\n",
" watchers See who is watching a file\n",
+ "(Use the --help-synonyms option for a list of alternate command names)\n",
NULL,
};
+static const char * const*
+cmd_synonyms ()
+{
+ char ** synonyms;
+ char ** line;
+ const struct cmd *c = &cmds[0];
+ int numcmds = 2; /* two more for title and end */
+
+ while (c->fullname != NULL)
+ {
+ numcmds++;
+ c++;
+ }
+
+ synonyms = (char **) xmalloc(numcmds * sizeof(char *));
+ line = synonyms;
+ *line++ = "CVS command synonyms are:\n";
+ for (c = &cmds[0]; c->fullname != NULL; c++)
+ {
+ if (c->nick1 || c->nick2)
+ {
+ *line = xmalloc(100); /* wild guess */
+ sprintf(*line, " %-12s %s %s\n", c->fullname,
+ c->nick1 ? c->nick1 : "",
+ c->nick2 ? c->nick2 : "");
+ line++;
+ }
+ }
+ *line = NULL;
+
+ return (const char * const*) synonyms; /* will never be freed */
+}
+
static RETSIGTYPE
main_cleanup (sig)
- int sig;
+ int sig;
{
+#ifndef DONT_USE_SIGNALS
const char *name;
+ char temp[10];
switch (sig)
{
- case SIGHUP:
- name = "hangup";
- break;
- case SIGINT:
- name = "interrupt";
- break;
- case SIGQUIT:
- name = "quit";
- break;
- case SIGPIPE:
- name = "broken pipe";
- break;
- case SIGTERM:
- name = "termination";
- break;
+#ifdef SIGHUP
+ case SIGHUP:
+ name = "hangup";
+ break;
+#endif
+#ifdef SIGINT
+ case SIGINT:
+ name = "interrupt";
+ break;
+#endif
+#ifdef SIGQUIT
+ case SIGQUIT:
+ name = "quit";
+ break;
+#endif
+#ifdef SIGPIPE
+ case SIGPIPE:
+ name = "broken pipe";
+ break;
+#endif
+#ifdef SIGTERM
+ case SIGTERM:
+ name = "termination";
+ break;
+#endif
+ default:
+ /* This case should never be reached, because we list above all
+ the signals for which we actually establish a signal handler. */
+ sprintf (temp, "%d", sig);
+ name = temp;
+ break;
}
- error (EXIT_FAILURE, 0, "received %s signal", name);
+ error (1, 0, "received %s signal", name);
+#endif /* !DONT_USE_SIGNALS */
}
static void
@@ -271,56 +302,66 @@ main (argc, argv)
int argc;
char **argv;
{
+ char *CVSroot = CVSROOT_DFLT;
extern char *version_string;
extern char *config_string;
char *cp, *end;
const struct cmd *cm;
int c, err = 0;
- static int help = FALSE;
- static int version_flag = FALSE;
- static int help_commands = FALSE;
- int rcsbin_update_env, cvs_update_env = 0;
+ int rcsbin_update_env, tmpdir_update_env, cvs_update_env;
+ int help = 0; /* Has the user asked for help? This
+ lets us support the `cvs -H cmd'
+ convention to give help for cmd. */
static struct option long_options[] =
{
- {"help", 0, &help, TRUE},
- {"version", 0, &version_flag, TRUE},
- {"help-commands", 0, &help_commands, TRUE},
+ {"help", 0, NULL, 'H'},
+ {"version", 0, NULL, 'v'},
+ {"help-commands", 0, NULL, 1},
+ {"help-synonyms", 0, NULL, 2},
{0, 0, 0, 0}
};
/* `getopt_long' stores the option index here, but right now we
don't use it. */
int option_index = 0;
+ int need_to_create_root = 0;
error_set_cleanup (error_cleanup);
-/* The socket subsystems on NT and OS2 must be initialized before use */
-#ifdef INITIALIZE_SOCKET_SUBSYSTEM
- INITIALIZE_SOCKET_SUBSYSTEM();
-#endif /* INITIALIZE_SOCKET_SUBSYSTEM */
+#ifdef SYSTEM_INITIALIZE
+ /* Hook for OS-specific behavior, for example socket subsystems on
+ NT and OS2 or dealing with windows and arguments on Mac. */
+ SYSTEM_INITIALIZE (&argc, &argv);
+#endif
/*
* Just save the last component of the path for error messages
*/
program_path = xstrdup (argv[0]);
+#ifdef ARGV0_NOT_PROGRAM_NAME
+ /* On some systems, e.g. VMS, argv[0] is not the name of the command
+ which the user types to invoke the program. */
+ program_name = "cvs";
+#else
program_name = last_component (argv[0]);
-
- CurDir = xmalloc (PATH_MAX);
-#ifndef SERVER_SUPPORT
- if (!getwd (CurDir))
- error (1, 0, "cannot get working directory: %s", CurDir);
#endif
/*
* Query the environment variables up-front, so that
* they can be overridden by command line arguments
*/
- rcsbin_update_env = *Rcsbin; /* RCSBIN_DFLT must be set */
cvs_update_env = 0;
+ rcsbin_update_env = *Rcsbin; /* RCSBIN_DFLT must be set */
if ((cp = getenv (RCSBIN_ENV)) != NULL)
{
Rcsbin = cp;
rcsbin_update_env = 0; /* it's already there */
}
+ tmpdir_update_env = *Tmpdir; /* TMPDIR_DFLT must be set */
+ if ((cp = getenv (TMPDIR_ENV)) != NULL)
+ {
+ Tmpdir = cp;
+ tmpdir_update_env = 0; /* it's already there */
+ }
if ((cp = getenv (EDITOR1_ENV)) != NULL)
Editor = cp;
else if ((cp = getenv (EDITOR2_ENV)) != NULL)
@@ -379,13 +420,18 @@ main (argc, argv)
opterr = 1;
while ((c = getopt_long
- (argc, argv, "Qqrwtnlvb:e:d:Hfz:s:", long_options, &option_index))
+ (argc, argv, "Qqrwtnlvb:T:e:d:Hfz:s:x", long_options, &option_index))
!= EOF)
{
switch (c)
{
- case 0:
- /* getopt_long took care of setting the flag. */
+ case 1:
+ /* --help-commands */
+ usage (cmd_usage);
+ break;
+ case 2:
+ /* --help-synonyms */
+ usage (cmd_synonyms());
break;
case 'Q':
really_quiet = TRUE;
@@ -408,12 +454,26 @@ main (argc, argv)
logoff = TRUE;
break;
case 'v':
- version_flag = TRUE;
+ (void) fputs (version_string, stdout);
+ (void) fputs (config_string, stdout);
+ (void) fputs ("\n", stdout);
+ (void) fputs ("Copyright (c) 1993-1994 Brian Berliner\n", stdout);
+ (void) fputs ("Copyright (c) 1993-1994 david d `zoo' zuhn\n", stdout);
+ (void) fputs ("Copyright (c) 1992, Brian Berliner and Jeff Polk\n", stdout);
+ (void) fputs ("Copyright (c) 1989-1992, Brian Berliner\n", stdout);
+ (void) fputs ("\n", stdout);
+ (void) fputs ("CVS may be copied only under the terms of the GNU General Public License,\n", stdout);
+ (void) fputs ("a copy of which can be found with the CVS distribution kit.\n", stdout);
+ exit (0);
break;
case 'b':
Rcsbin = optarg;
rcsbin_update_env = 1; /* need to update environment */
break;
+ case 'T':
+ Tmpdir = optarg;
+ tmpdir_update_env = 1; /* need to update environment */
+ break;
case 'e':
Editor = optarg;
break;
@@ -422,11 +482,10 @@ main (argc, argv)
cvs_update_env = 1; /* need to update environment */
break;
case 'H':
- use_cvsrc = FALSE; /* this ensure that cvs -H works */
- help = TRUE;
+ help = 1;
break;
case 'f':
- use_cvsrc = FALSE;
+ use_cvsrc = FALSE; /* unnecessary, since we've done it above */
break;
case 'z':
#ifdef CLIENT_SUPPORT
@@ -442,314 +501,306 @@ main (argc, argv)
case 's':
variable_set (optarg);
break;
+ case 'x':
+#ifdef CLIENT_SUPPORT
+ cvsencrypt = 1;
+#endif /* CLIENT_SUPPORT */
+ /* If no CLIENT_SUPPORT, ignore -x, so that users can
+ have it in their .cvsrc and not cause any trouble.
+ If no ENCRYPTION, we still accept -x, but issue an
+ error if we are being run as a client. */
+ break;
case '?':
default:
usage (usg);
}
}
- if (version_flag == TRUE)
- {
- (void) fputs (version_string, stdout);
- (void) fputs (config_string, stdout);
- (void) fputs ("\n", stdout);
- (void) fputs ("Copyright (c) 1993-1994 Brian Berliner\n", stdout);
- (void) fputs ("Copyright (c) 1993-1994 david d `zoo' zuhn\n", stdout);
- (void) fputs ("Copyright (c) 1992, Brian Berliner and Jeff Polk\n", stdout);
- (void) fputs ("Copyright (c) 1989-1992, Brian Berliner\n", stdout);
- (void) fputs ("\n", stdout);
- (void) fputs ("CVS may be copied only under the terms of the GNU General Public License,\n", stdout);
- (void) fputs ("a copy of which can be found with the CVS distribution kit.\n", stdout);
- exit (0);
- }
- else if (help_commands)
- usage (cmd_usage);
-
argc -= optind;
argv += optind;
if (argc < 1)
usage (usg);
-#ifdef HAVE_KERBEROS
- /* If we are invoked with a single argument "kserver", then we are
- running as Kerberos server as root. Do the authentication as
- the very first thing, to minimize the amount of time we are
- running as root. */
- if (strcmp (argv[0], "kserver") == 0)
+
+ /* Look up the command name. */
+
+ command_name = argv[0];
+ for (cm = cmds; cm->fullname; cm++)
{
- int status;
- char instance[INST_SZ];
- struct sockaddr_in peer;
- struct sockaddr_in laddr;
- int len;
- KTEXT_ST ticket;
- AUTH_DAT auth;
- char version[KRB_SENDAUTH_VLEN];
- Key_schedule sched;
- char user[ANAME_SZ];
- struct passwd *pw;
-
- strcpy (instance, "*");
- len = sizeof peer;
- if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0
- || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr,
- &len) < 0)
- {
- printf ("E Fatal error, aborting.\n\
-error %s getpeername or getsockname failed\n", strerror (errno));
- exit (EXIT_FAILURE);
- }
+ if (cm->nick1 && !strcmp (command_name, cm->nick1))
+ break;
+ if (cm->nick2 && !strcmp (command_name, cm->nick2))
+ break;
+ if (!strcmp (command_name, cm->fullname))
+ break;
+ }
- status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd",
- instance, &peer, &laddr, &auth, "", sched,
- version);
- if (status != KSUCCESS)
- {
- printf ("E Fatal error, aborting.\n\
-error 0 kerberos: %s\n", krb_get_err_text(status));
- exit (EXIT_FAILURE);
- }
+ if (!cm->fullname)
+ usage (cmd_usage); /* no match */
+ else
+ command_name = cm->fullname; /* Global pointer for later use */
- /* Get the local name. */
- status = krb_kntoln (&auth, user);
- if (status != KSUCCESS)
- {
- printf ("E Fatal error, aborting.\n\
-error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status));
- exit (EXIT_FAILURE);
- }
+ if (strcmp (argv[0], "rlog") == 0)
+ {
+ error (0, 0, "warning: the rlog command is deprecated");
+ error (0, 0, "use the synonymous log command instead");
+ }
- pw = getpwnam (user);
- if (pw == NULL)
- {
- printf ("E Fatal error, aborting.\n\
-error 0 %s: no such user\n", user);
- exit (EXIT_FAILURE);
- }
+ if (help)
+ argc = -1; /* some functions only check for this */
+ else
+ {
+ /* The user didn't ask for help, so go ahead and authenticate,
+ set up CVSROOT, and the rest of it. */
- initgroups (pw->pw_name, pw->pw_gid);
- setgid (pw->pw_gid);
- setuid (pw->pw_uid);
- /* Inhibit access by randoms. Don't want people randomly
- changing our temporary tree before we check things in. */
- umask (077);
+ /* The UMASK environment variable isn't handled with the
+ others above, since we don't want to signal errors if the
+ user has asked for help. This won't work if somebody adds
+ a command-line flag to set the umask, since we'll have to
+ parse it before we get here. */
-#if HAVE_PUTENV
- /* Set LOGNAME and USER in the environment, in case they are
- already set to something else. */
+ if ((cp = getenv (CVSUMASK_ENV)) != NULL)
{
- char *env;
+ /* FIXME: Should be accepting symbolic as well as numeric mask. */
+ cvsumask = strtol (cp, &end, 8) & 0777;
+ if (*end != '\0')
+ error (1, errno, "invalid umask value in %s (%s)",
+ CVSUMASK_ENV, cp);
+ }
- env = xmalloc (sizeof "LOGNAME=" + strlen (user));
- (void) sprintf (env, "LOGNAME=%s", user);
- (void) putenv (env);
+#if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT)
+ /* If we are invoked with a single argument "kserver", then we are
+ running as Kerberos server as root. Do the authentication as
+ the very first thing, to minimize the amount of time we are
+ running as root. */
+ if (strcmp (command_name, "kserver") == 0)
+ {
+ kserver_authenticate_connection ();
- env = xmalloc (sizeof "USER=" + strlen (user));
- (void) sprintf (env, "USER=%s", user);
- (void) putenv (env);
+ /* Pretend we were invoked as a plain server. */
+ command_name = "server";
}
-#endif
-
- /* Pretend we were invoked as a plain server. */
- argv[0] = "server";
- }
#endif /* HAVE_KERBEROS */
#if defined(AUTH_SERVER_SUPPORT) && defined(SERVER_SUPPORT)
- if (strcmp (argv[0], "pserver") == 0)
- {
- /* Gets username and password from client, authenticates, then
- switches to run as that user and sends an ACK back to the
- client. */
- authenticate_connection ();
+ if (strcmp (command_name, "pserver") == 0)
+ {
+ /* Gets username and password from client, authenticates, then
+ switches to run as that user and sends an ACK back to the
+ client. */
+ pserver_authenticate_connection ();
- /* Pretend we were invoked as a plain server. */
- argv[0] = "server";
- }
+ /* Pretend we were invoked as a plain server. */
+ command_name = "server";
+ }
#endif /* AUTH_SERVER_SUPPORT && SERVER_SUPPORT */
- /*
- * See if we are able to find a 'better' value for CVSroot in the
- * CVSADM_ROOT directory.
- */
-#ifdef SERVER_SUPPORT
- if (strcmp (argv[0], "server") == 0 && CVSroot == NULL)
- CVSADM_Root = NULL;
- else
- CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
-#else /* No SERVER_SUPPORT */
- CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
-#endif /* No SERVER_SUPPORT */
- if (CVSADM_Root != NULL)
- {
- if (CVSroot == NULL || !cvs_update_env)
- {
- CVSroot = CVSADM_Root;
- cvs_update_env = 1; /* need to update environment */
- }
-#ifdef CLIENT_SUPPORT
- else if (!getenv ("CVS_IGNORE_REMOTE_ROOT"))
-#else /* ! CLIENT_SUPPORT */
- else
-#endif /* CLIENT_SUPPORT */
- {
- /*
- * Now for the hard part, compare the two directories. If they
- * are not identical, then abort this command.
- */
- if ((fncmp (CVSroot, CVSADM_Root) != 0) &&
- !same_directories(CVSroot, CVSADM_Root))
- {
- error (0, 0, "%s value for CVS Root found in %s",
- CVSADM_Root, CVSADM_ROOT);
- error (0, 0, "does not match command line -d %s setting",
- CVSroot);
- error (1, 0,
- "you may wish to try the cvs command again without the -d option ");
- }
- }
- }
-
- /* CVSroot may need fixing up, if an access-method was specified,
- * but not a user. Later code assumes that if CVSroot contains an
- * access-method, then it also has a user. We print a warning and
- * die if we can't guarantee that.
- */
- if (CVSroot
- && *CVSroot
- && (CVSroot[0] == ':')
- && (strchr (CVSroot, '@') == NULL))
- {
- error (1, 0,
- "must also give a username if specifying access method");
- }
+ /* Fiddling with CVSROOT doesn't make sense if we're running
+ in server mode, since the client will send the repository
+ directory after the connection is made. */
- /*
- * Specifying just the '-H' flag to the sub-command causes a Usage
- * message to be displayed.
- */
- command_name = cp = argv[0];
- if (help == TRUE || (argc > 1 && strcmp (argv[1], "-H") == 0))
- argc = -1;
- else
- {
- /*
- * Check to see if we can write into the history file. If not,
- * we assume that we can't work in the repository.
- * BUT, only if the history file exists.
- */
#ifdef SERVER_SUPPORT
- if (strcmp (command_name, "server") != 0 || CVSroot != NULL)
+ if (strcmp (command_name, "server") != 0)
#endif
{
- char path[PATH_MAX];
- int save_errno;
-
- if (!CVSroot || !*CVSroot)
- error (1, 0, "You don't have a %s environment variable",
- CVSROOT_ENV);
- (void) sprintf (path, "%s/%s", CVSroot, CVSROOTADM);
- if (!isaccessible (path, R_OK | X_OK))
+ char *CVSADM_Root;
+
+ /* See if we are able to find a 'better' value for CVSroot
+ in the CVSADM_ROOT directory. */
+
+ CVSADM_Root = NULL;
+
+ /* "cvs import" shouldn't check CVS/Root; in general it
+ ignores CVS directories and CVS/Root is likely to
+ specify a different repository than the one we are
+ importing to. */
+#if 0
+ if (lookup_command_attribute (command_name) & CVS_CMD_IGNORE_ADMROOT)
+ CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
+#else
+ if (strcmp (command_name, "import") != 0)
+ CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
+#endif
+ if (CVSADM_Root != NULL)
{
- save_errno = errno;
- /* If this is "cvs init", the root need not exist yet. */
- if (strcmp (command_name, "init") != 0
+ if (CVSroot == NULL || !cvs_update_env)
+ {
+ CVSroot = CVSADM_Root;
+ cvs_update_env = 1; /* need to update environment */
+ }
+ /* Let -d override CVS/Root file. The user might want
+ to change the access method, use a different server
+ (if there are two server machines which share the
+ repository using a networked file system), etc. */
+ else if (
#ifdef CLIENT_SUPPORT
- /* If we are a remote client, the root need not exist
- on the client machine (FIXME: we should also skip
- the check for CVSROOTADM_HISTORY being writable;
- it shouldn't matter if there is a read-only file
- which happens to have the same name on the client
- machine). */
- && strchr (CVSroot, ':') == NULL)
+ !getenv ("CVS_IGNORE_REMOTE_ROOT") &&
#endif
+ strcmp (CVSroot, CVSADM_Root) != 0)
{
- error (0, 0,
- "Sorry, you don't have sufficient access to %s", CVSroot);
- error (1, save_errno, "%s", path);
+ /* Once we have verified that this root is usable,
+ we will want to write it into CVS/Root.
+
+ Don't do it for the "login" command, however.
+ Consider: if the user executes "cvs login" with
+ the working directory inside an already checked
+ out module, we'd incorrectly change the
+ CVS/Root file to reflect the CVSROOT of the
+ "cvs login" command. Ahh, the things one
+ discovers. */
+
+#if 0
+ if (lookup_command_attribute (command_name) & CVS_CMD_USES_WORK_DIR)
+#else
+ if ((strcmp (command_name, "checkout") != 0) &&
+ (strcmp (command_name, "login") != 0) &&
+ (strcmp (command_name, "rdiff") != 0) &&
+ (strcmp (command_name, "release") != 0) &&
+ (strcmp (command_name, "rtag") != 0))
+#endif
+ need_to_create_root = 1;
}
}
- (void) strcat (path, "/");
- (void) strcat (path, CVSROOTADM_HISTORY);
- if (readonlyfs == 0 && isfile (path) && !isaccessible (path, R_OK | W_OK))
+
+ /* Now we've reconciled CVSROOT from the command line, the
+ CVS/Root file, and the environment variable. Do the
+ last sanity checks on the variable. */
+
+ if (! CVSroot)
{
- save_errno = errno;
error (0, 0,
- "Sorry, you don't have read/write access to the history file");
- error (1, save_errno, "%s", path);
+ "No CVSROOT specified! Please use the `-d' option");
+ error (1, 0,
+ "or set the %s environment variable.", CVSROOT_ENV);
+ }
+
+ if (! *CVSroot)
+ {
+ error (0, 0,
+ "CVSROOT is set but empty! Make sure that the");
+ error (0, 0,
+ "specification of CVSROOT is legal, either via the");
+ error (0, 0,
+ "`-d' option, the %s environment variable, or the",
+ CVSROOT_ENV);
+ error (1, 0,
+ "CVS/Root file (if any).");
}
- parseopts();
- }
- }
-#ifdef SERVER_SUPPORT
- if (strcmp (command_name, "server") == 0)
- /* This is only used for writing into the history file. Might
- be nice to have hostname and/or remote path, on the other hand
- I'm not sure whether it is worth the trouble. */
- strcpy (CurDir, "<remote>");
- else if (!getwd (CurDir))
- error (1, 0, "cannot get working directory: %s", CurDir);
-#endif
+ /* Now we're 100% sure that we have a valid CVSROOT
+ variable. Parse it to see if we're supposed to do
+ remote accesses or use a special access method. */
+
+ if (parse_cvsroot (CVSroot))
+ error (1, 0, "Bad CVSROOT.");
+
+ /*
+ * Check to see if we can write into the history file. If not,
+ * we assume that we can't work in the repository.
+ * BUT, only if the history file exists.
+ */
+
+ if (!client_active)
+ {
+ char path[PATH_MAX];
+ int save_errno;
+
+ (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
+ if (!isaccessible (path, R_OK | X_OK))
+ {
+ save_errno = errno;
+ /* If this is "cvs init", the root need not exist yet. */
+ if (strcmp (command_name, "init") != 0)
+ {
+ error (1, save_errno, "%s", path);
+ }
+ }
+ (void) strcat (path, "/");
+ (void) strcat (path, CVSROOTADM_HISTORY);
+ if (readonlyfs == 0 && isfile (path) && !isaccessible (path, R_OK | W_OK))
+ {
+ save_errno = errno;
+ error (0, 0, "Sorry, you don't have read/write access to the history file");
+ error (1, save_errno, "%s", path);
+ }
+ }
#ifdef HAVE_PUTENV
- /* Now, see if we should update the environment with the Rcsbin value */
- if (cvs_update_env)
- {
- char *env;
+ /* Update the CVSROOT environment variable if necessary. */
- env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot) + 1 + 1);
- (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
- (void) putenv (env);
- /* do not free env, as putenv has control of it */
- }
- if (rcsbin_update_env)
- {
- char *env;
+ if (cvs_update_env)
+ {
+ char *env;
+ env = xmalloc (strlen (CVSROOT_ENV) + strlen (CVSroot)
+ + 1 + 1);
+ (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot);
+ (void) putenv (env);
+ /* do not free env, as putenv has control of it */
+ }
+#endif
+ }
+
+ /* This is only used for writing into the history file. For
+ remote connections, it might be nice to have hostname
+ and/or remote path, on the other hand I'm not sure whether
+ it is worth the trouble. */
- env = xmalloc (strlen (RCSBIN_ENV) + strlen (Rcsbin) + 1 + 1);
- (void) sprintf (env, "%s=%s", RCSBIN_ENV, Rcsbin);
- (void) putenv (env);
- /* do not free env, as putenv has control of it */
- }
+ CurDir = xmalloc (PATH_MAX);
+#ifdef SERVER_SUPPORT
+ if (strcmp (command_name, "server") == 0)
+ strcpy (CurDir, "<remote>");
+ else
#endif
+ {
+ if (!getwd (CurDir))
+ error (1, 0, "cannot get working directory: %s", CurDir);
+ }
- /*
- * If Rcsbin is set to something, make sure it is terminated with
- * a slash character. If not, add one.
- */
- if (*Rcsbin)
- {
- int len = strlen (Rcsbin);
- char *rcsbin;
+ if (Tmpdir == NULL || Tmpdir[0] == '\0')
+ Tmpdir = "/tmp";
- if (Rcsbin[len - 1] != '/')
+#ifdef HAVE_PUTENV
+ /* Now, see if we should update the environment with the
+ Rcsbin value */
+ if (rcsbin_update_env)
{
- rcsbin = Rcsbin;
- Rcsbin = xmalloc (len + 2); /* one for '/', one for NULL */
- (void) strcpy (Rcsbin, rcsbin);
- (void) strcat (Rcsbin, "/");
+ char *env;
+ env = xmalloc (strlen (RCSBIN_ENV) + strlen (Rcsbin) + 1 + 1);
+ (void) sprintf (env, "%s=%s", RCSBIN_ENV, Rcsbin);
+ (void) putenv (env);
+ /* do not free env, as putenv has control of it */
}
- }
+ if (tmpdir_update_env)
+ {
+ char *env;
+ env = xmalloc (strlen (TMPDIR_ENV) + strlen (Tmpdir) + 1 + 1);
+ (void) sprintf (env, "%s=%s", TMPDIR_ENV, Tmpdir);
+ (void) putenv (env);
+ /* do not free env, as putenv has control of it */
+ }
+#endif
- for (cm = cmds; cm->fullname; cm++)
- {
- if (cm->nick1 && !strcmp (cp, cm->nick1))
- break;
- if (cm->nick2 && !strcmp (cp, cm->nick2))
- break;
- if (!strcmp (cp, cm->fullname))
- break;
- }
+ /*
+ * If Rcsbin is set to something, make sure it is terminated with
+ * a slash character. If not, add one.
+ */
+ if (*Rcsbin)
+ {
+ int len = strlen (Rcsbin);
+ char *rcsbin;
- if (!cm->fullname)
- usage (usg); /* no match */
- else
- {
- command_name = cm->fullname; /* Global pointer for later use */
+ if (Rcsbin[len - 1] != '/')
+ {
+ rcsbin = Rcsbin;
+ Rcsbin = xmalloc (len + 2); /* one for '/', one for NULL */
+ (void) strcpy (Rcsbin, rcsbin);
+ (void) strcat (Rcsbin, "/");
+ }
+ }
+#ifndef DONT_USE_SIGNALS
/* make sure we clean up on error */
#ifdef SIGHUP
(void) SIG_register (SIGHUP, main_cleanup);
@@ -771,6 +822,7 @@ error 0 %s: no such user\n", user);
(void) SIG_register (SIGTERM, main_cleanup);
(void) SIG_register (SIGTERM, Lock_Cleanup);
#endif
+#endif /* !DONT_USE_SIGNALS */
gethostname(hostname, sizeof (hostname));
@@ -779,28 +831,47 @@ error 0 %s: no such user\n", user);
* Make stdout line buffered, so 'tail -f' can monitor progress.
* Patch creates too much output to monitor and it runs slowly.
*/
+# ifndef KLUDGE_FOR_WNT_TESTSUITE
+
if (strcmp (cm->fullname, "patch"))
+# ifdef BUFSIZ /* traditional SysV chokes when size == 0 */
+ (void) setvbuf (stdout, (char *) NULL, _IOLBF, BUFSIZ);
+# else
(void) setvbuf (stdout, (char *) NULL, _IOLBF, 0);
-#endif
+# endif
+
+# else /* KLUDGE_FOR_WNT_TESTSUITE */
+
+ (void) setvbuf (stdout, (char *) NULL, _IONBF, 0);
+ (void) setvbuf (stderr, (char *) NULL, _IONBF, 0);
+
+# endif /* KLUDGE_FOR_WNT_TESTSUITE */
+
+#endif /* HAVE_SETVBUF */
if (use_cvsrc)
- read_cvsrc (&argc, &argv, command_name);
+ read_cvsrc (&argc, &argv, command_name);
-#ifdef CLIENT_SUPPORT
- /* If cvsroot contains a colon, try to do it via the protocol. */
- {
- char *p = CVSroot == NULL ? NULL : strchr (CVSroot, ':');
- if (p)
- err = (*(cm->client_func)) (argc, argv);
- else
- err = (*(cm->func)) (argc, argv);
- }
-#else /* No CLIENT_SUPPORT */
- err = (*(cm->func)) (argc, argv);
+ } /* end of stuff that gets done if the user DOESN'T ask for help */
-#endif /* No CLIENT_SUPPORT */
+ err = (*(cm->func)) (argc, argv);
+
+ if (need_to_create_root)
+ {
+ /* Update the CVS/Root file. We might want to do this in
+ all directories that we recurse into, but currently we
+ don't. */
+ Create_Root (NULL, CVSroot);
}
+
Lock_Cleanup ();
+
+#ifdef SYSTEM_CLEANUP
+ /* Hook for OS-specific behavior, for example socket subsystems on
+ NT and OS2 or dealing with windows and arguments on Mac. */
+ SYSTEM_CLEANUP ();
+#endif
+
if (err)
return (EXIT_FAILURE);
return 0;
diff --git a/gnu/usr.bin/cvs/src/patch.c b/gnu/usr.bin/cvs/src/patch.c
index 97977344e48..fd0fdd0295e 100644
--- a/gnu/usr.bin/cvs/src/patch.c
+++ b/gnu/usr.bin/cvs/src/patch.c
@@ -16,8 +16,10 @@
#include "getline.h"
static RETSIGTYPE patch_cleanup PROTO((void));
-static Dtype patch_dirproc PROTO((char *dir, char *repos, char *update_dir));
-static int patch_fileproc PROTO((struct file_info *finfo));
+static Dtype patch_dirproc PROTO ((void *callerdat, char *dir,
+ char *repos, char *update_dir,
+ List *entries));
+static int patch_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int patch_proc PROTO((int *pargc, char **argv, char *xwhere,
char *mwhere, char *mfile, int shorten,
int local_specified, char *mname, char *msg));
@@ -28,12 +30,14 @@ static int toptwo_diffs = 0;
static int local = 0;
static char *options = NULL;
static char *rev1 = NULL;
-static int rev1_validated = 1;
+static int rev1_validated = 0;
static char *rev2 = NULL;
-static int rev2_validated = 1;
+static int rev2_validated = 0;
static char *date1 = NULL;
static char *date2 = NULL;
-static char tmpfile1[L_tmpnam+1], tmpfile2[L_tmpnam+1], tmpfile3[L_tmpnam+1];
+static char *tmpfile1 = NULL;
+static char *tmpfile2 = NULL;
+static char *tmpfile3 = NULL;
static int unidiff = 0;
static const char *const patch_usage[] =
@@ -253,7 +257,7 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
int which;
char repository[PATH_MAX];
- (void) sprintf (repository, "%s/%s", CVSroot, argv[0]);
+ (void) sprintf (repository, "%s/%s", CVSroot_directory, argv[0]);
(void) strcpy (where, argv[0]);
/* if mfile isn't null, we need to set up to do only part of the module */
@@ -295,7 +299,7 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
}
/* cd to the starting repository */
- if (chdir (repository) < 0)
+ if ( CVS_CHDIR (repository) < 0)
{
error (0, errno, "cannot chdir to %s", repository);
return (1);
@@ -319,8 +323,9 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
/* start the recursion processor */
err = start_recursion (patch_fileproc, (FILESDONEPROC) NULL, patch_dirproc,
- (DIRLEAVEPROC) NULL, *pargc - 1, argv + 1, local,
- which, 0, 1, where, 1, 1);
+ (DIRLEAVEPROC) NULL, NULL,
+ *pargc - 1, argv + 1, local,
+ which, 0, 1, where, 1);
return (err);
}
@@ -331,7 +336,8 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
*/
/* ARGSUSED */
static int
-patch_fileproc (finfo)
+patch_fileproc (callerdat, finfo)
+ void *callerdat;
struct file_info *finfo;
{
struct utimbuf t;
@@ -362,7 +368,15 @@ patch_fileproc (finfo)
if (isattic && rev2 == NULL && date2 == NULL)
vers_head = NULL;
else
- vers_head = RCS_getversion (rcsfile, rev2, date2, force_tag_match, 0);
+ {
+ vers_head = RCS_getversion (rcsfile, rev2, date2, force_tag_match,
+ (int *) NULL);
+ if (vers_head != NULL && RCS_isdead (rcsfile, vers_head))
+ {
+ free (vers_head);
+ vers_head = NULL;
+ }
+ }
if (toptwo_diffs)
{
@@ -380,9 +394,15 @@ patch_fileproc (finfo)
return (1);
}
}
- vers_tag = RCS_getversion (rcsfile, rev1, date1, force_tag_match, 0);
+ vers_tag = RCS_getversion (rcsfile, rev1, date1, force_tag_match,
+ (int *) NULL);
+ if (vers_tag != NULL && RCS_isdead (rcsfile, vers_tag))
+ {
+ free (vers_tag);
+ vers_tag = NULL;
+ }
- if (vers_tag == NULL && (vers_head == NULL || isattic))
+ if (vers_tag == NULL && vers_head == NULL)
return (0); /* nothing known about specified revs */
if (vers_tag && vers_head && strcmp (vers_head, vers_tag) == 0)
@@ -409,22 +429,27 @@ patch_fileproc (finfo)
vers_tag, vers_head);
return (0);
}
- if ((fp1 = fopen (tmpnam (tmpfile1), "w+")) != NULL)
+ tmpfile1 = cvs_temp_name ();
+ if ((fp1 = CVS_FOPEN (tmpfile1, "w+")) != NULL)
(void) fclose (fp1);
- if ((fp2 = fopen (tmpnam (tmpfile2), "w+")) != NULL)
+ tmpfile2 = cvs_temp_name ();
+ if ((fp2 = CVS_FOPEN (tmpfile2, "w+")) != NULL)
(void) fclose (fp2);
- if ((fp3 = fopen (tmpnam (tmpfile3), "w+")) != NULL)
+ tmpfile3 = cvs_temp_name ();
+ if ((fp3 = CVS_FOPEN (tmpfile3, "w+")) != NULL)
(void) fclose (fp3);
if (fp1 == NULL || fp2 == NULL || fp3 == NULL)
{
+ /* FIXME: should be printing a proper error message, with errno-based
+ message, and the filename which we could not create. */
error (0, 0, "cannot create temporary files");
ret = 1;
goto out;
}
if (vers_tag != NULL)
{
- retcode = RCS_checkout (rcsfile->path, NULL, vers_tag, options, tmpfile1,
- 0, 0);
+ retcode = RCS_checkout (rcsfile, (char *) NULL, vers_tag,
+ (char *) NULL, options, tmpfile1);
if (retcode != 0)
{
if (!really_quiet)
@@ -445,7 +470,8 @@ patch_fileproc (finfo)
}
if (vers_head != NULL)
{
- retcode = RCS_checkout (rcsfile->path, NULL, vers_head, options, tmpfile2, 0, 0);
+ retcode = RCS_checkout (rcsfile, (char *) NULL, vers_head,
+ (char *) NULL, options, tmpfile2);
if (retcode != 0)
{
if (!really_quiet)
@@ -522,8 +548,8 @@ patch_fileproc (finfo)
goto out;
}
}
- if (CVSroot != NULL)
- (void) sprintf (strippath, "%s/", CVSroot);
+ if (CVSroot_directory != NULL)
+ (void) sprintf (strippath, "%s/", CVSroot_directory);
else
(void) strcpy (strippath, REPOS_STRIP);
if (strncmp (rcs, strippath, strlen (strippath)) == 0)
@@ -568,9 +594,13 @@ patch_fileproc (finfo)
if (line2)
free (line2);
/* FIXME: should be checking for errors. */
- (void) unlink (tmpfile1);
- (void) unlink (tmpfile2);
- (void) unlink (tmpfile3);
+ (void) CVS_UNLINK (tmpfile1);
+ (void) CVS_UNLINK (tmpfile2);
+ (void) CVS_UNLINK (tmpfile3);
+ free (tmpfile1);
+ free (tmpfile2);
+ free (tmpfile3);
+ tmpfile1 = tmpfile2 = tmpfile3 = NULL;
return (ret);
}
@@ -579,10 +609,12 @@ patch_fileproc (finfo)
*/
/* ARGSUSED */
static Dtype
-patch_dirproc (dir, repos, update_dir)
+patch_dirproc (callerdat, dir, repos, update_dir, entries)
+ void *callerdat;
char *dir;
char *repos;
char *update_dir;
+ List *entries;
{
if (!quiet)
error (0, 0, "Diffing %s", update_dir);
@@ -595,10 +627,20 @@ patch_dirproc (dir, repos, update_dir)
static RETSIGTYPE
patch_cleanup ()
{
- if (tmpfile1[0] != '\0')
+ if (tmpfile1 != NULL)
+ {
(void) unlink_file (tmpfile1);
- if (tmpfile2[0] != '\0')
+ free (tmpfile1);
+ }
+ if (tmpfile2 != NULL)
+ {
(void) unlink_file (tmpfile2);
- if (tmpfile3[0] != '\0')
+ free (tmpfile2);
+ }
+ if (tmpfile3 != NULL)
+ {
(void) unlink_file (tmpfile3);
+ free (tmpfile3);
+ }
+ tmpfile1 = tmpfile2 = tmpfile3 = NULL;
}
diff --git a/gnu/usr.bin/cvs/src/rcscmds.c b/gnu/usr.bin/cvs/src/rcscmds.c
index 66aea57447a..7b2c440d5fc 100644
--- a/gnu/usr.bin/cvs/src/rcscmds.c
+++ b/gnu/usr.bin/cvs/src/rcscmds.c
@@ -12,28 +12,73 @@
#include "cvs.h"
#include <assert.h>
+/* This file, rcs.h, and rcs.c, are intended to define our interface
+ to RCS files. As of July, 1996, there are still a few places that
+ still exec RCS commands directly. The intended long-term direction
+ is to have CVS access RCS files via an RCS library (rcs.c can be
+ considered a start at one), for performance, cleanliness (CVS has
+ some awful hacks to work around RCS behaviors which don't make
+ sense for CVS), installation hassles, ease of implementing the CVS
+ server (I don't think that the output-out-of-order bug can be
+ completely fixed as long as CVS calls RCS), and perhaps other
+ reasons.
+
+ Whether there will also be a version of RCS which uses this
+ library, or whether the library will be packaged for uses beyond
+ CVS or RCS (many people would like such a thing) is an open
+ question. Some considerations:
+
+ 1. An RCS library for CVS must have the capabilities of the
+ existing CVS code which accesses RCS files. In particular, simple
+ approaches will often be slow.
+
+ 2. An RCS library should not use the code from the current RCS
+ (5.7 and its ancestors). The code has many problems. Too few
+ comments, too many layers of abstraction, too many global variables
+ (the correct number for a library is zero), too much intricately
+ interwoven functionality, and too many clever hacks. Paul Eggert,
+ the current RCS maintainer, agrees.
+
+ 3. More work needs to be done in terms of separating out the RCS
+ library from the rest of CVS (for example, cvs_output should be
+ replaced by a callback, and the declarations should be centralized
+ into rcs.h, and probably other such cleanups).
+
+ 4. To be useful for RCS and perhaps for other uses, the library
+ may need features beyond those needed by CVS.
+
+ 5. Any changes to the RCS file format *must* be compatible. Many,
+ many tools (not just CVS and RCS) can at least import this format.
+ RCS and CVS must preserve the current ability to import/export it
+ (preferably improved--magic branches are currently a roadblock).
+ TODO: improve rcsfile.5 in the RCS distribution so that it more
+ completely documents this format.
+
+ On somewhat related notes:
+
+ 1. A library for diff is an obvious idea. The one thing which I'm
+ not so sure about is that I think CVS probably wants the ability to
+ allow arbitrarily-bizarre (and possibly customized for particular
+ file formats) external diff programs.
+
+ 2. A library for patch is another such idea. CVS's needs are
+ smaller than the functionality of the standalone patch program (it
+ only calls patch in the client, and only needs to be able to patch
+ unmodified versions, which is something that RCS_deltas already
+ does in a different context). But it is silly for CVS to be making
+ people install patch as well as CVS for such a simple purpose. */
+
/* For RCS file PATH, make symbolic tag TAG point to revision REV.
This validates that TAG is OK for a user to use. Return value is
-1 for error (and errno is set to indicate the error), positive for
error (and an error message has been printed), or zero for success. */
int
-RCS_settag(path, tag, rev)
+RCS_exec_settag(path, tag, rev)
const char *path;
const char *tag;
const char *rev;
{
- if (strcmp (tag, TAG_BASE) == 0
- || strcmp (tag, TAG_HEAD) == 0)
- {
- /* Print the name of the tag might be considered redundant
- with the caller, which also prints it. Perhaps this helps
- clarify why the tag name is considered reserved, I don't
- know. */
- error (0, 0, "Attempt to add reserved tag name %s", tag);
- return 1;
- }
-
run_setup ("%s%s -x,v/ -q -N%s:%s", Rcsbin, RCS, tag, rev);
run_arg (path);
return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
@@ -42,7 +87,7 @@ RCS_settag(path, tag, rev)
/* NOERR is 1 to suppress errors--FIXME it would
be better to avoid the errors or some cleaner solution. */
int
-RCS_deltag(path, tag, noerr)
+RCS_exec_deltag(path, tag, noerr)
const char *path;
const char *tag;
int noerr;
@@ -54,7 +99,7 @@ RCS_deltag(path, tag, noerr)
/* set RCS branch to REV */
int
-RCS_setbranch(path, rev)
+RCS_exec_setbranch(path, rev)
const char *path;
const char *rev;
{
@@ -66,7 +111,7 @@ RCS_setbranch(path, rev)
/* Lock revision REV. NOERR is 1 to suppress errors--FIXME it would
be better to avoid the errors or some cleaner solution. */
int
-RCS_lock(path, rev, noerr)
+RCS_exec_lock(path, rev, noerr)
const char *path;
const char *rev;
int noerr;
@@ -79,7 +124,7 @@ RCS_lock(path, rev, noerr)
/* Unlock revision REV. NOERR is 1 to suppress errors--FIXME it would
be better to avoid the errors or some cleaner solution. */
int
-RCS_unlock(path, rev, noerr)
+RCS_exec_unlock(path, rev, noerr)
const char *path;
const char *rev;
int noerr;
@@ -119,24 +164,19 @@ RCS_merge(path, options, rev1, rev2)
}
/* Check out a revision from RCSFILE into WORKFILE, or to standard output
- if WORKFILE is NULL. If WORKFILE is "", let RCS pick the working file
- name. TAG is the tag to check out, or NULL if one should check out
- the head of the default branch. OPTIONS is a string such as
- -kb or -kkv, for keyword expansion options, or NULL if there are none.
- If WORKFILE is NULL, run regardless of noexec; if non-NULL, noexec
- inhibits execution. SOUT is what to do with standard output
- (typically RUN_TTY). If FLAGS & RCS_FLAGS_LOCK, lock it. If
- FLAGS & RCS_FLAGS_FORCE, check out even on top of an existing file.
- If NOERR is nonzero, suppress errors. */
+ if WORKFILE is NULL. TAG is the tag to check out, or NULL if one
+ should check out the head of the default branch. OPTIONS is a string
+ such as -kb or -kkv, for keyword expansion options, or NULL if there
+ are none. If WORKFILE is NULL, run regardless of noexec; if non-NULL,
+ noexec inhibits execution. SOUT is what to do with standard output
+ (typically RUN_TTY). */
int
-RCS_checkout (rcsfile, workfile, tag, options, sout, flags, noerr)
+RCS_exec_checkout (rcsfile, workfile, tag, options, sout)
char *rcsfile;
char *workfile;
char *tag;
char *options;
char *sout;
- int flags;
- int noerr;
{
run_setup ("%s%s -x,v/ -q %s%s", Rcsbin, RCS_CO,
tag ? "-r" : "", tag ? tag : "");
@@ -144,33 +184,27 @@ RCS_checkout (rcsfile, workfile, tag, options, sout, flags, noerr)
run_arg (options);
if (workfile == NULL)
run_arg ("-p");
- if (flags & RCS_FLAGS_LOCK)
- run_arg ("-l");
- if (flags & RCS_FLAGS_FORCE)
- run_arg ("-f");
run_arg (rcsfile);
- if (workfile != NULL && workfile[0] != '\0')
+ if (workfile != NULL)
run_arg (workfile);
- return run_exec (RUN_TTY, sout, noerr ? DEVNULL : RUN_TTY,
+ return run_exec (RUN_TTY, sout, RUN_TTY,
workfile == NULL ? (RUN_NORMAL | RUN_REALLY) : RUN_NORMAL);
}
/* Check in to RCSFILE with revision REV (which must be greater than the
largest revision) and message MESSAGE (which is checked for legality).
- If FLAGS & RCS_FLAGS_DEAD, check in a dead revision. If NOERR, do not
- report errors. If FLAGS & RCS_FLAGS_QUIET suppress errors somewhat more
- selectively. If FLAGS & RCS_FLAGS_MODTIME, use the working file's
- modification time for the checkin time. WORKFILE is the working file
- to check in from, or NULL to use the usual RCS rules for deriving it
- from the RCSFILE. */
+ If FLAGS & RCS_FLAGS_DEAD, check in a dead revision. If FLAGS &
+ RCS_FLAGS_QUIET, tell ci to be quiet. If FLAGS & RCS_FLAGS_MODTIME,
+ use the working file's modification time for the checkin time.
+ WORKFILE is the working file to check in from, or NULL to use the usual
+ RCS rules for deriving it from the RCSFILE. */
int
-RCS_checkin (rcsfile, workfile, message, rev, flags, noerr)
+RCS_checkin (rcsfile, workfile, message, rev, flags)
char *rcsfile;
char *workfile;
char *message;
char *rev;
int flags;
- int noerr;
{
run_setup ("%s%s -x,v/ -f %s%s", Rcsbin, RCS_CI,
rev ? "-r" : "", rev ? rev : "");
@@ -184,5 +218,5 @@ RCS_checkin (rcsfile, workfile, message, rev, flags, noerr)
if (workfile != NULL)
run_arg (workfile);
run_arg (rcsfile);
- return run_exec (RUN_TTY, RUN_TTY, noerr ? DEVNULL : RUN_TTY, RUN_NORMAL);
+ return run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
}
diff --git a/gnu/usr.bin/cvs/src/server.c b/gnu/usr.bin/cvs/src/server.c
index 9e9b09018f3..35f73d90951 100644
--- a/gnu/usr.bin/cvs/src/server.c
+++ b/gnu/usr.bin/cvs/src/server.c
@@ -3,9 +3,28 @@
#include "watch.h"
#include "edit.h"
#include "fileattr.h"
+#include "getline.h"
+#include "buffer.h"
#ifdef SERVER_SUPPORT
+#if defined (AUTH_SERVER_SUPPORT) || defined (HAVE_KERBEROS)
+#include <sys/socket.h>
+#endif
+
+#ifdef HAVE_KERBEROS
+#include <netinet/in.h>
+#include <krb.h>
+#ifndef HAVE_KRB_GET_ERR_TEXT
+#define krb_get_err_text(status) krb_err_txt[status]
+#endif
+
+/* Information we need if we are going to use Kerberos encryption. */
+static C_Block kblock;
+static Key_schedule sched;
+
+#endif
+
/* for select */
#include <sys/types.h>
#ifdef HAVE_SYS_BSDTYPES_H
@@ -25,7 +44,18 @@
#define O_NONBLOCK O_NDELAY
#endif
+/* EWOULDBLOCK is not defined by POSIX, but some BSD systems will
+ return it, rather than EAGAIN, for nonblocking writes. */
+#ifdef EWOULDBLOCK
+#define blocking_error(err) ((err) == EWOULDBLOCK || (err) == EAGAIN)
+#else
+#define blocking_error(err) ((err) == EAGAIN)
+#endif
+
#ifdef AUTH_SERVER_SUPPORT
+#ifdef HAVE_GETSPNAM
+#include <shadow.h>
+#endif
/* For initgroups(). */
#if HAVE_INITGROUPS
#include <grp.h>
@@ -50,6 +80,13 @@ int status PROTO((int argc, char **argv));
int tag PROTO((int argc, char **argv));
int update PROTO((int argc, char **argv));
+/* While processing requests, this buffer accumulates data to be sent to
+ the client, and then once we are in do_cvs_command, we use it
+ for all the data to be sent. */
+static struct buffer *buf_to_net;
+
+/* This buffer is used to read input from the client. */
+static struct buffer *buf_from_net;
/*
* This is where we stash stuff we are going to use. Format string
@@ -57,64 +94,189 @@ int update PROTO((int argc, char **argv));
*/
static char *server_temp_dir;
+/* This is the original value of server_temp_dir, before any possible
+ changes inserted by serve_max_dotdot. */
+static char *orig_server_temp_dir;
+
/* Nonzero if we should keep the temp directory around after we exit. */
static int dont_delete_temp;
-static char no_mem_error;
-#define NO_MEM_ERROR (&no_mem_error)
-
static void server_write_entries PROTO((void));
-/*
- * Read a line from the stream "instream" without command line editing.
- *
- * Action is compatible with "readline", e.g. space for the result is
- * malloc'd and should be freed by the caller.
- *
- * A NULL return means end of file. A return of NO_MEM_ERROR means
- * that we are out of memory.
- */
-static char *read_line PROTO((FILE *));
+/* All server communication goes through buffer structures. Most of
+ the buffers are built on top of a file descriptor. This structure
+ is used as the closure field in a buffer. */
-static char *
-read_line (stream)
- FILE *stream;
+struct fd_buffer
{
- int c;
- char *result;
- int input_index = 0;
- int result_size = 80;
-
- fflush (stdout);
- result = (char *) malloc (result_size);
- if (result == NULL)
- return NO_MEM_ERROR;
-
- while (1)
+ /* The file descriptor. */
+ int fd;
+ /* Nonzero if the file descriptor is in blocking mode. */
+ int blocking;
+};
+
+static struct buffer *fd_buffer_initialize
+ PROTO ((int, int, void (*) (struct buffer *)));
+static int fd_buffer_input PROTO((void *, char *, int, int, int *));
+static int fd_buffer_output PROTO((void *, const char *, int, int *));
+static int fd_buffer_flush PROTO((void *));
+static int fd_buffer_block PROTO((void *, int));
+
+/* Initialize a buffer built on a file descriptor. FD is the file
+ descriptor. INPUT is nonzero if this is for input, zero if this is
+ for output. MEMORY is the function to call when a memory error
+ occurs. */
+
+static struct buffer *
+fd_buffer_initialize (fd, input, memory)
+ int fd;
+ int input;
+ void (*memory) PROTO((struct buffer *));
+{
+ struct fd_buffer *n;
+
+ n = (struct fd_buffer *) xmalloc (sizeof *n);
+ n->fd = fd;
+ n->blocking = 1;
+ return buf_initialize (input ? fd_buffer_input : NULL,
+ input ? NULL : fd_buffer_output,
+ input ? NULL : fd_buffer_flush,
+ fd_buffer_block,
+ (int (*) PROTO((void *))) NULL,
+ memory,
+ n);
+}
+
+/* The buffer input function for a buffer built on a file descriptor. */
+
+static int
+fd_buffer_input (closure, data, need, size, got)
+ void *closure;
+ char *data;
+ int need;
+ int size;
+ int *got;
+{
+ struct fd_buffer *fd = (struct fd_buffer *) closure;
+ int nbytes;
+
+ if (! fd->blocking)
+ nbytes = read (fd->fd, data, size);
+ else
{
- c = fgetc (stream);
-
- if (c == EOF)
- {
- free (result);
- return NULL;
- }
-
- if (c == '\n')
- break;
-
- result[input_index++] = c;
- while (input_index >= result_size)
+ /* This case is not efficient. Fortunately, I don't think it
+ ever actually happens. */
+ nbytes = read (fd->fd, data, need == 0 ? 1 : need);
+ }
+
+ if (nbytes > 0)
+ {
+ *got = nbytes;
+ return 0;
+ }
+
+ *got = 0;
+
+ if (nbytes == 0)
+ {
+ /* End of file. This assumes that we are using POSIX or BSD
+ style nonblocking I/O. On System V we will get a zero
+ return if there is no data, even when not at EOF. */
+ return -1;
+ }
+
+ /* Some error occurred. */
+
+ if (blocking_error (errno))
+ {
+ /* Everything's fine, we just didn't get any data. */
+ return 0;
+ }
+
+ return errno;
+}
+
+/* The buffer output function for a buffer built on a file descriptor. */
+
+static int
+fd_buffer_output (closure, data, have, wrote)
+ void *closure;
+ const char *data;
+ int have;
+ int *wrote;
+{
+ struct fd_buffer *fd = (struct fd_buffer *) closure;
+
+ *wrote = 0;
+
+ while (have > 0)
+ {
+ int nbytes;
+
+ nbytes = write (fd->fd, data, have);
+
+ if (nbytes <= 0)
{
- result_size *= 2;
- result = (char *) realloc (result, result_size);
- if (result == NULL)
- return NO_MEM_ERROR;
+ if (! fd->blocking
+ && (nbytes == 0 || blocking_error (errno)))
+ {
+ /* A nonblocking write failed to write any data. Just
+ return. */
+ return 0;
+ }
+
+ /* Some sort of error occurred. */
+
+ if (nbytes == 0)
+ return EIO;
+
+ return errno;
}
+
+ *wrote += nbytes;
+ data += nbytes;
+ have -= nbytes;
}
-
- result[input_index++] = '\0';
- return result;
+
+ return 0;
+}
+
+/* The buffer flush function for a buffer built on a file descriptor. */
+
+/*ARGSUSED*/
+static int
+fd_buffer_flush (closure)
+ void *closure;
+{
+ /* Nothing to do. File descriptors are always flushed. */
+ return 0;
+}
+
+/* The buffer block function for a buffer built on a file descriptor. */
+
+static int
+fd_buffer_block (closure, block)
+ void *closure;
+ int block;
+{
+ struct fd_buffer *fd = (struct fd_buffer *) closure;
+ int flags;
+
+ flags = fcntl (fd->fd, F_GETFL, 0);
+ if (flags < 0)
+ return errno;
+
+ if (block)
+ flags &= ~O_NONBLOCK;
+ else
+ flags |= O_NONBLOCK;
+
+ if (fcntl (fd->fd, F_SETFL, flags) < 0)
+ return errno;
+
+ fd->blocking = block;
+
+ return 0;
}
/*
@@ -176,17 +338,20 @@ mkdir_p (dir)
* Print the error response for error code STATUS. The caller is
* reponsible for making sure we get back to the command loop without
* any further output occuring.
+ * Must be called only in contexts where it is OK to send output.
*/
static void
print_error (status)
int status;
{
char *msg;
- printf ("error ");
+ buf_output0 (buf_to_net, "error ");
msg = strerror (status);
if (msg)
- printf ("%s", msg);
- printf ("\n");
+ buf_output0 (buf_to_net, msg);
+ buf_append_char (buf_to_net, '\n');
+
+ buf_flush (buf_to_net, 0);
}
static int pending_error;
@@ -196,17 +361,22 @@ static int pending_error;
*/
static char *pending_error_text;
-/* If an error is pending, print it and return 1. If not, return 0. */
+/* If an error is pending, print it and return 1. If not, return 0.
+ Must be called only in contexts where it is OK to send output. */
static int
print_pending_error ()
{
if (pending_error_text)
{
- printf ("%s\n", pending_error_text);
+ buf_output0 (buf_to_net, pending_error_text);
+ buf_append_char (buf_to_net, '\n');
if (pending_error)
print_error (pending_error);
else
- printf ("error \n");
+ buf_output0 (buf_to_net, "error \n");
+
+ buf_flush (buf_to_net, 0);
+
pending_error = 0;
free (pending_error_text);
pending_error_text = NULL;
@@ -270,8 +440,14 @@ serve_valid_responses (arg)
{
if (rs->status == rs_essential)
{
- printf ("E response `%s' not supported by client\nerror \n",
- rs->name);
+ buf_output0 (buf_to_net, "E response `");
+ buf_output0 (buf_to_net, rs->name);
+ buf_output0 (buf_to_net, "' not supported by client\nerror \n");
+
+ /* FIXME: This call to buf_flush could conceivably
+ cause deadlock, as noted in server_cleanup. */
+ buf_flush (buf_to_net, 1);
+
exit (EXIT_FAILURE);
}
else if (rs->status == rs_optional)
@@ -286,13 +462,14 @@ serve_root (arg)
char *arg;
{
char *env;
- extern char *CVSroot;
char path[PATH_MAX];
int save_errno;
if (error_pending()) return;
+
+ set_local_cvsroot (arg);
- (void) sprintf (path, "%s/%s", arg, CVSROOTADM);
+ (void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
if (!isaccessible (path, R_OK | X_OK))
{
save_errno = errno;
@@ -313,21 +490,14 @@ Sorry, you don't have read/write access to the history file %s", path);
pending_error = save_errno;
}
- CVSroot = malloc (strlen (arg) + 1);
- if (CVSroot == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (CVSroot, arg);
#ifdef HAVE_PUTENV
- env = malloc (strlen (CVSROOT_ENV) + strlen (CVSroot) + 1 + 1);
+ env = malloc (strlen (CVSROOT_ENV) + strlen (CVSroot_directory) + 1 + 1);
if (env == NULL)
{
pending_error = ENOMEM;
return;
}
- (void) sprintf (env, "%s=%s", CVSROOT_ENV, arg);
+ (void) sprintf (env, "%s=%s", CVSROOT_ENV, CVSroot_directory);
(void) putenv (env);
/* do not free env, as putenv has control of it */
#endif
@@ -358,7 +528,8 @@ serve_max_dotdot (arg)
strcpy (p, server_temp_dir);
for (i = 0; i < lim; ++i)
strcat (p, "/d");
- free (server_temp_dir);
+ if (server_temp_dir != orig_server_temp_dir)
+ free (server_temp_dir);
server_temp_dir = p;
}
@@ -371,6 +542,7 @@ dirswitch (dir, repos)
{
int status;
FILE *f;
+ char *b;
server_write_entries ();
@@ -399,7 +571,13 @@ dirswitch (dir, repos)
sprintf(pending_error_text, "E cannot mkdir %s", dir_name);
return;
}
- if (chdir (dir_name) < 0)
+
+ b = strrchr (dir_name, '/');
+ *b = '\0';
+ Subdir_Register ((List *) NULL, dir_name, b + 1);
+ *b = '/';
+
+ if ( CVS_CHDIR (dir_name) < 0)
{
pending_error = errno;
pending_error_text = malloc (80 + strlen(dir_name));
@@ -418,13 +596,33 @@ dirswitch (dir, repos)
pending_error = errno;
return;
}
- f = fopen (CVSADM_REP, "w");
+ f = CVS_FOPEN (CVSADM_REP, "w");
if (f == NULL)
{
pending_error = errno;
return;
}
- if (fprintf (f, "%s\n", repos) < 0)
+ if (fprintf (f, "%s", repos) < 0)
+ {
+ pending_error = errno;
+ fclose (f);
+ return;
+ }
+ /* Non-remote CVS handles a module representing the entire tree
+ (e.g., an entry like ``world -a .'') by putting /. at the end
+ of the Repository file, so we do the same. */
+ if (strcmp (dir, ".") == 0
+ && CVSroot_directory != NULL
+ && strcmp (CVSroot_directory, repos) == 0)
+ {
+ if (fprintf (f, "/.") < 0)
+ {
+ pending_error = errno;
+ fclose (f);
+ return;
+ }
+ }
+ if (fprintf (f, "\n") < 0)
{
pending_error = errno;
fclose (f);
@@ -435,7 +633,9 @@ dirswitch (dir, repos)
pending_error = errno;
return;
}
- f = fopen (CVSADM_ENT, "w+");
+ /* We open in append mode because we don't want to clobber an
+ existing Entries file. */
+ f = CVS_FOPEN (CVSADM_ENT, "a");
if (f == NULL)
{
pending_error = errno;
@@ -463,35 +663,38 @@ static void
serve_directory (arg)
char *arg;
{
+ int status;
char *repos;
+
use_dir_and_repos = 1;
- repos = read_line (stdin);
- if (repos == NULL)
+ status = buf_read_line (buf_from_net, &repos, (int *) NULL);
+ if (status == 0)
{
- pending_error_text = malloc (80 + strlen (arg));
- if (pending_error_text)
- {
- if (feof (stdin))
- sprintf (pending_error_text,
- "E end of file reading mode for %s", arg);
- else
- {
- sprintf (pending_error_text,
- "E error reading mode for %s", arg);
- pending_error = errno;
- }
- }
- else
- pending_error = ENOMEM;
+ dirswitch (arg, repos);
+ free (repos);
}
- else if (repos == NO_MEM_ERROR)
+ else if (status == -2)
{
- pending_error = ENOMEM;
+ pending_error = ENOMEM;
}
else
{
- dirswitch (arg, repos);
- free (repos);
+ pending_error_text = malloc (80 + strlen (arg));
+ if (pending_error_text == NULL)
+ {
+ pending_error = ENOMEM;
+ }
+ else if (status == -1)
+ {
+ sprintf (pending_error_text,
+ "E end of file reading mode for %s", arg);
+ }
+ else
+ {
+ sprintf (pending_error_text,
+ "E error reading mode for %s", arg);
+ pending_error = status;
+ }
}
}
@@ -500,7 +703,10 @@ serve_static_directory (arg)
char *arg;
{
FILE *f;
- f = fopen (CVSADM_ENTSTAT, "w+");
+
+ if (error_pending ()) return;
+
+ f = CVS_FOPEN (CVSADM_ENTSTAT, "w+");
if (f == NULL)
{
pending_error = errno;
@@ -522,7 +728,10 @@ serve_sticky (arg)
char *arg;
{
FILE *f;
- f = fopen (CVSADM_TAG, "w+");
+
+ if (error_pending ()) return;
+
+ f = CVS_FOPEN (CVSADM_TAG, "w+");
if (f == NULL)
{
pending_error = errno;
@@ -547,7 +756,7 @@ serve_sticky (arg)
}
/*
- * Read SIZE bytes from stdin, write them to FILE.
+ * Read SIZE bytes from buf_from_net, write them to FILE.
*
* Currently this isn't really used for receiving parts of a file --
* the file is still sent over in one chunk. But if/when we get
@@ -560,62 +769,67 @@ receive_partial_file (size, file)
int size;
int file;
{
- char buf[16*1024], *bufp;
- int toread, nread, nwrote;
while (size > 0)
{
- toread = sizeof (buf);
- if (toread > size)
- toread = size;
+ int status, nread;
+ char *data;
- nread = fread (buf, 1, toread, stdin);
- if (nread <= 0)
+ status = buf_read_data (buf_from_net, size, &data, &nread);
+ if (status != 0)
{
- if (feof (stdin))
+ if (status == -2)
+ pending_error = ENOMEM;
+ else
{
pending_error_text = malloc (80);
- if (pending_error_text)
+ if (pending_error_text == NULL)
+ pending_error = ENOMEM;
+ else if (status == -1)
{
sprintf (pending_error_text,
"E premature end of file from client");
pending_error = 0;
}
else
- pending_error = ENOMEM;
- }
- else if (ferror (stdin))
- {
- pending_error_text = malloc (40);
- if (pending_error_text)
+ {
sprintf (pending_error_text,
"E error reading from client");
- pending_error = errno;
- }
- else
- {
- pending_error_text = malloc (40);
- if (pending_error_text)
- sprintf (pending_error_text,
- "E short read from client");
- pending_error = 0;
+ pending_error = status;
+ }
}
return;
}
+
size -= nread;
- bufp = buf;
- while (nread)
+
+ while (nread > 0)
{
- nwrote = write (file, bufp, nread);
+ int nwrote;
+
+ nwrote = write (file, data, nread);
if (nwrote < 0)
{
pending_error_text = malloc (40);
- if (pending_error_text)
+ if (pending_error_text != NULL)
sprintf (pending_error_text, "E unable to write");
pending_error = errno;
+
+ /* Read and discard the file data. */
+ while (size > 0)
+ {
+ int status, nread;
+ char *data;
+
+ status = buf_read_data (buf_from_net, size, &data, &nread);
+ if (status != 0)
+ return;
+ size -= nread;
+ }
+
return;
}
nread -= nwrote;
- bufp += nwrote;
+ data += nwrote;
}
}
}
@@ -633,7 +847,7 @@ receive_file (size, file, gzipped)
int gzip_status;
/* Write the file. */
- fd = open (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd < 0)
{
pending_error_text = malloc (40 + strlen (arg));
@@ -690,78 +904,102 @@ static void
serve_modified (arg)
char *arg;
{
- int size;
+ int size, status;
char *size_text;
char *mode_text;
int gzipped = 0;
- if (error_pending ()) return;
+ /*
+ * This used to return immediately if error_pending () was true.
+ * However, that fails, because it causes each line of the file to
+ * be echoed back to the client as an unrecognized command. The
+ * client isn't reading from the socket, so eventually both
+ * processes block trying to write to the other. Now, we try to
+ * read the file if we can.
+ */
- mode_text = read_line (stdin);
- if (mode_text == NULL)
+ status = buf_read_line (buf_from_net, &mode_text, (int *) NULL);
+ if (status != 0)
{
- pending_error_text = malloc (80 + strlen (arg));
- if (pending_error_text)
+ if (status == -2)
+ pending_error = ENOMEM;
+ else
{
- if (feof (stdin))
- sprintf (pending_error_text,
- "E end of file reading mode for %s", arg);
+ pending_error_text = malloc (80 + strlen (arg));
+ if (pending_error_text == NULL)
+ pending_error = ENOMEM;
else
{
- sprintf (pending_error_text,
- "E error reading mode for %s", arg);
- pending_error = errno;
+ if (status == -1)
+ sprintf (pending_error_text,
+ "E end of file reading mode for %s", arg);
+ else
+ {
+ sprintf (pending_error_text,
+ "E error reading mode for %s", arg);
+ pending_error = status;
+ }
}
}
- else
- pending_error = ENOMEM;
- return;
- }
- else if (mode_text == NO_MEM_ERROR)
- {
- pending_error = ENOMEM;
return;
}
- size_text = read_line (stdin);
- if (size_text == NULL)
+
+ status = buf_read_line (buf_from_net, &size_text, (int *) NULL);
+ if (status != 0)
{
- pending_error_text = malloc (80 + strlen (arg));
- if (pending_error_text)
+ if (status == -2)
+ pending_error = ENOMEM;
+ else
{
- if (feof (stdin))
- sprintf (pending_error_text,
- "E end of file reading size for %s", arg);
+ pending_error_text = malloc (80 + strlen (arg));
+ if (pending_error_text == NULL)
+ pending_error = ENOMEM;
else
{
- sprintf (pending_error_text,
- "E error reading size for %s", arg);
- pending_error = errno;
+ if (status == -1)
+ sprintf (pending_error_text,
+ "E end of file reading size for %s", arg);
+ else
+ {
+ sprintf (pending_error_text,
+ "E error reading size for %s", arg);
+ pending_error = errno;
+ }
}
}
- else
- pending_error = ENOMEM;
- return;
- }
- else if (size_text == NO_MEM_ERROR)
- {
- pending_error = ENOMEM;
return;
}
if (size_text[0] == 'z')
- {
+ {
gzipped = 1;
size = atoi (size_text + 1);
- }
+ }
else
- size = atoi (size_text);
+ size = atoi (size_text);
free (size_text);
+ if (error_pending ())
+ {
+ /* Now that we know the size, read and discard the file data. */
+ while (size > 0)
+ {
+ int status, nread;
+ char *data;
+
+ status = buf_read_data (buf_from_net, size, &data, &nread);
+ if (status != 0)
+ return;
+ size -= nread;
+ }
+ return;
+ }
+
if (size >= 0)
- {
+ {
receive_file (size, arg, gzipped);
if (error_pending ()) return;
- }
+ }
{
int status = change_mode (arg, mode_text);
@@ -791,7 +1029,7 @@ static void
serve_enable_unchanged (arg)
char *arg;
{
- use_unchanged = 1;
+ use_unchanged = 1;
}
static void
@@ -806,7 +1044,7 @@ serve_lost (arg)
else
{
struct utimbuf ut;
- int fd = open (arg, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+ int fd = CVS_OPEN (arg, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0 || close (fd) < 0)
{
pending_error = errno;
@@ -922,7 +1160,12 @@ server_write_entries ()
/* Note that we free all the entries regardless of errors. */
if (!error_pending ())
{
- f = fopen (CVSADM_ENT, "w");
+ /* We open in append mode because we don't want to clobber an
+ existing Entries file. If we are checking out a module
+ which explicitly lists more than one file in a particular
+ directory, then we will wind up calling
+ server_write_entries for each such file. */
+ f = CVS_FOPEN (CVSADM_ENT, "a");
if (f == NULL)
{
pending_error = errno;
@@ -985,6 +1228,7 @@ serve_notify (arg)
{
struct notify_note *new;
char *data;
+ int status;
if (error_pending ()) return;
@@ -1011,28 +1255,29 @@ serve_notify (arg)
}
strcpy (new->filename, arg);
- data = read_line (stdin);
- if (data == NULL)
+ status = buf_read_line (buf_from_net, &data, (int *) NULL);
+ if (status != 0)
{
- pending_error_text = malloc (80 + strlen (arg));
- if (pending_error_text)
+ if (status == -2)
+ pending_error = ENOMEM;
+ else
{
- if (feof (stdin))
- sprintf (pending_error_text,
- "E end of file reading mode for %s", arg);
+ pending_error_text = malloc (80 + strlen (arg));
+ if (pending_error_text == NULL)
+ pending_error = ENOMEM;
else
{
- sprintf (pending_error_text,
- "E error reading mode for %s", arg);
- pending_error = errno;
+ if (status == -1)
+ sprintf (pending_error_text,
+ "E end of file reading notification for %s", arg);
+ else
+ {
+ sprintf (pending_error_text,
+ "E error reading notification for %s", arg);
+ pending_error = status;
+ }
}
}
- else
- pending_error = ENOMEM;
- }
- else if (data == NO_MEM_ERROR)
- {
- pending_error = ENOMEM;
}
else
{
@@ -1099,7 +1344,7 @@ server_notify ()
while (notify_list != NULL)
{
- if (chdir (notify_list->dir) < 0)
+ if ( CVS_CHDIR (notify_list->dir) < 0)
{
error (0, errno, "cannot change to %s", notify_list->dir);
return -1;
@@ -1120,20 +1365,21 @@ server_notify ()
notify_do (*notify_list->type, notify_list->filename, getcaller(),
notify_list->val, notify_list->watches, repos);
- printf ("Notified ");
+ buf_output0 (buf_to_net, "Notified ");
if (use_dir_and_repos)
{
char *dir = notify_list->dir + strlen (server_temp_dir) + 1;
if (dir[0] == '\0')
- fputs (".", stdout);
+ buf_append_char (buf_to_net, '.');
else
- fputs (dir, stdout);
- fputs ("/\n", stdout);
+ buf_output0 (buf_to_net, dir);
+ buf_append_char (buf_to_net, '/');
+ buf_append_char (buf_to_net, '\n');
}
- fputs (repos, stdout);
- fputs ("/", stdout);
- fputs (notify_list->filename, stdout);
- fputs ("\n", stdout);
+ buf_output0 (buf_to_net, repos);
+ buf_append_char (buf_to_net, '/');
+ buf_output0 (buf_to_net, notify_list->filename);
+ buf_append_char (buf_to_net, '\n');
p = notify_list->next;
free (notify_list->filename);
@@ -1149,9 +1395,11 @@ server_notify ()
Lock_Cleanup ();
dellist (&list);
}
- /* do_cvs_command writes to stdout via write(), not stdio, so better
- flush out the buffer. */
- fflush (stdout);
+
+ /* The code used to call fflush (stdout) here, but that is no
+ longer necessary. The data is now buffered in buf_to_net,
+ which will be flushed by the caller, do_cvs_command. */
+
return 0;
}
@@ -1254,62 +1502,27 @@ serve_set (arg)
put into pending_error. */
variable_set (arg);
}
-
-/*
- * We must read data from a child process and send it across the
- * network. We do not want to block on writing to the network, so we
- * store the data from the child process in memory. A BUFFER
- * structure holds the status of one communication, and uses a linked
- * list of buffer_data structures to hold data.
- */
-struct buffer
-{
- /* Data. */
- struct buffer_data *data;
-
- /* Last buffer on data chain. */
- struct buffer_data *last;
-
- /* File descriptor to write to or read from. */
- int fd;
+#ifdef ENCRYPTION
+#ifdef HAVE_KERBEROS
- /* Nonzero if this is an output buffer (sanity check). */
- int output;
-
- /* Nonzero if the file descriptor is in nonblocking mode. */
- int nonblocking;
-
- /* Function to call if we can't allocate memory. */
- void (*memory_error) PROTO((struct buffer *));
-};
-
-/* Data is stored in lists of these structures. */
-
-struct buffer_data
+static void
+serve_kerberos_encrypt (arg)
+ char *arg;
{
- /* Next buffer in linked list. */
- struct buffer_data *next;
-
- /*
- * A pointer into the data area pointed to by the text field. This
- * is where to find data that has not yet been written out.
- */
- char *bufp;
-
- /* The number of data bytes found at BUFP. */
- int size;
-
- /*
- * Actual buffer. This never changes after the structure is
- * allocated. The buffer is BUFFER_DATA_SIZE bytes.
- */
- char *text;
-};
-
-/* The size we allocate for each buffer_data structure. */
-#define BUFFER_DATA_SIZE (4096)
+ /* All future communication with the client will be encrypted. */
+
+ buf_to_net = krb_encrypt_buffer_initialize (buf_to_net, 0, sched,
+ kblock,
+ buf_to_net->memory_error);
+ buf_from_net = krb_encrypt_buffer_initialize (buf_from_net, 1, sched,
+ kblock,
+ buf_from_net->memory_error);
+}
+#endif /* HAVE_KERBEROS */
+#endif /* ENCRYPTION */
+
#ifdef SERVER_FLOWCONTROL
/* The maximum we'll queue to the remote client before blocking. */
# ifndef SERVER_HI_WATER
@@ -1319,275 +1532,10 @@ struct buffer_data
# ifndef SERVER_LO_WATER
# define SERVER_LO_WATER (1 * 1024 * 1024)
# endif /* SERVER_LO_WATER */
-#endif /* SERVER_FLOWCONTROL */
-
-/* Linked list of available buffer_data structures. */
-static struct buffer_data *free_buffer_data;
-
-static void allocate_buffer_datas PROTO((void));
-static inline struct buffer_data *get_buffer_data PROTO((void));
-static int buf_empty_p PROTO((struct buffer *));
-static void buf_output PROTO((struct buffer *, const char *, int));
-static void buf_output0 PROTO((struct buffer *, const char *));
-static inline void buf_append_char PROTO((struct buffer *, int));
-static int buf_send_output PROTO((struct buffer *));
-static int set_nonblock PROTO((struct buffer *));
-static int set_block PROTO((struct buffer *));
-static int buf_send_counted PROTO((struct buffer *));
-static inline void buf_append_data PROTO((struct buffer *,
- struct buffer_data *,
- struct buffer_data *));
-static int buf_read_file PROTO((FILE *, long, struct buffer_data **,
- struct buffer_data **));
-static int buf_input_data PROTO((struct buffer *, int *));
-static void buf_copy_lines PROTO((struct buffer *, struct buffer *, int));
-static int buf_copy_counted PROTO((struct buffer *, struct buffer *));
-#ifdef SERVER_FLOWCONTROL
-static int buf_count_mem PROTO((struct buffer *));
static int set_nonblock_fd PROTO((int));
-#endif /* SERVER_FLOWCONTROL */
-
-/* Allocate more buffer_data structures. */
-
-static void
-allocate_buffer_datas ()
-{
- struct buffer_data *alc;
- char *space;
- int i;
-
- /* Allocate buffer_data structures in blocks of 16. */
-#define ALLOC_COUNT (16)
-
- alc = ((struct buffer_data *)
- malloc (ALLOC_COUNT * sizeof (struct buffer_data)));
- space = (char *) valloc (ALLOC_COUNT * BUFFER_DATA_SIZE);
- if (alc == NULL || space == NULL)
- return;
- for (i = 0; i < ALLOC_COUNT; i++, alc++, space += BUFFER_DATA_SIZE)
- {
- alc->next = free_buffer_data;
- free_buffer_data = alc;
- alc->text = space;
- }
-}
-
-/* Get a new buffer_data structure. */
-
-static inline struct buffer_data *
-get_buffer_data ()
-{
- struct buffer_data *ret;
-
- if (free_buffer_data == NULL)
- {
- allocate_buffer_datas ();
- if (free_buffer_data == NULL)
- return NULL;
- }
-
- ret = free_buffer_data;
- free_buffer_data = ret->next;
- return ret;
-}
-
-/* See whether a buffer is empty. */
-
-static int
-buf_empty_p (buf)
- struct buffer *buf;
-{
- struct buffer_data *data;
-
- for (data = buf->data; data != NULL; data = data->next)
- if (data->size > 0)
- return 0;
- return 1;
-}
-
-#ifdef SERVER_FLOWCONTROL
-/*
- * Count how much data is stored in the buffer..
- * Note that each buffer is a malloc'ed chunk BUFFER_DATA_SIZE.
- */
-
-static int
-buf_count_mem (buf)
- struct buffer *buf;
-{
- struct buffer_data *data;
- int mem = 0;
-
- for (data = buf->data; data != NULL; data = data->next)
- mem += BUFFER_DATA_SIZE;
-
- return mem;
-}
-#endif /* SERVER_FLOWCONTROL */
-
-/* Add data DATA of length LEN to BUF. */
-
-static void
-buf_output (buf, data, len)
- struct buffer *buf;
- const char *data;
- int len;
-{
- if (buf->data != NULL
- && (((buf->last->text + BUFFER_DATA_SIZE)
- - (buf->last->bufp + buf->last->size))
- >= len))
- {
- memcpy (buf->last->bufp + buf->last->size, data, len);
- buf->last->size += len;
- return;
- }
-
- while (1)
- {
- struct buffer_data *newdata;
-
- newdata = get_buffer_data ();
- if (newdata == NULL)
- {
- (*buf->memory_error) (buf);
- return;
- }
-
- if (buf->data == NULL)
- buf->data = newdata;
- else
- buf->last->next = newdata;
- newdata->next = NULL;
- buf->last = newdata;
-
- newdata->bufp = newdata->text;
-
- if (len <= BUFFER_DATA_SIZE)
- {
- newdata->size = len;
- memcpy (newdata->text, data, len);
- return;
- }
-
- newdata->size = BUFFER_DATA_SIZE;
- memcpy (newdata->text, data, BUFFER_DATA_SIZE);
-
- data += BUFFER_DATA_SIZE;
- len -= BUFFER_DATA_SIZE;
- }
-
- /*NOTREACHED*/
-}
-
-/* Add a '\0' terminated string to BUF. */
-
-static void
-buf_output0 (buf, string)
- struct buffer *buf;
- const char *string;
-{
- buf_output (buf, string, strlen (string));
-}
-
-/* Add a single character to BUF. */
-
-static inline void
-buf_append_char (buf, ch)
- struct buffer *buf;
- int ch;
-{
- if (buf->data != NULL
- && (buf->last->text + BUFFER_DATA_SIZE
- != buf->last->bufp + buf->last->size))
- {
- *(buf->last->bufp + buf->last->size) = ch;
- ++buf->last->size;
- }
- else
- {
- char b;
-
- b = ch;
- buf_output (buf, &b, 1);
- }
-}
/*
- * Send all the output we've been saving up. Returns 0 for success or
- * errno code. If the buffer has been set to be nonblocking, this
- * will just write until the write would block.
- */
-
-static int
-buf_send_output (buf)
- struct buffer *buf;
-{
- if (! buf->output)
- abort ();
-
- while (buf->data != NULL)
- {
- struct buffer_data *data;
-
- data = buf->data;
- while (data->size > 0)
- {
- int nbytes;
-
- nbytes = write (buf->fd, data->bufp, data->size);
- if (nbytes <= 0)
- {
- int status;
-
- if (buf->nonblocking
- && (nbytes == 0
-#ifdef EWOULDBLOCK
- || errno == EWOULDBLOCK
-#endif
- || errno == EAGAIN))
- {
- /*
- * A nonblocking write failed to write any data.
- * Just return.
- */
- return 0;
- }
-
- /*
- * An error, or EOF. Throw away all the data and
- * return.
- */
- if (nbytes == 0)
- status = EIO;
- else
- status = errno;
-
- buf->last->next = free_buffer_data;
- free_buffer_data = buf->data;
- buf->data = NULL;
- buf->last = NULL;
-
- return status;
- }
-
- data->size -= nbytes;
- data->bufp += nbytes;
- }
-
- buf->data = data->next;
- data->next = free_buffer_data;
- free_buffer_data = data;
- }
-
- buf->last = NULL;
-
- return 0;
-}
-
-#ifdef SERVER_FLOWCONTROL
-/*
* Set buffer BUF to non-blocking I/O. Returns 0 for success or errno
* code.
*/
@@ -1605,553 +1553,9 @@ set_nonblock_fd (fd)
return errno;
return 0;
}
-#endif /* SERVER_FLOWCONTROL */
-
-static int
-set_nonblock (buf)
- struct buffer *buf;
-{
- int flags;
-
- if (buf->nonblocking)
- return 0;
- flags = fcntl (buf->fd, F_GETFL, 0);
- if (flags < 0)
- return errno;
- if (fcntl (buf->fd, F_SETFL, flags | O_NONBLOCK) < 0)
- return errno;
- buf->nonblocking = 1;
- return 0;
-}
-
-/*
- * Set buffer BUF to blocking I/O. Returns 0 for success or errno
- * code.
- */
-
-static int
-set_block (buf)
- struct buffer *buf;
-{
- int flags;
-
- if (! buf->nonblocking)
- return 0;
- flags = fcntl (buf->fd, F_GETFL, 0);
- if (flags < 0)
- return errno;
- if (fcntl (buf->fd, F_SETFL, flags & ~O_NONBLOCK) < 0)
- return errno;
- buf->nonblocking = 0;
- return 0;
-}
-
-/*
- * Send a character count and some output. Returns errno code or 0 for
- * success.
- *
- * Sending the count in binary is OK since this is only used on a pipe
- * within the same system.
- */
-
-static int
-buf_send_counted (buf)
- struct buffer *buf;
-{
- int size;
- struct buffer_data *data;
-
- if (! buf->output)
- abort ();
-
- size = 0;
- for (data = buf->data; data != NULL; data = data->next)
- size += data->size;
-
- data = get_buffer_data ();
- if (data == NULL)
- {
- (*buf->memory_error) (buf);
- return ENOMEM;
- }
-
- data->next = buf->data;
- buf->data = data;
- if (buf->last == NULL)
- buf->last = data;
-
- data->bufp = data->text;
- data->size = sizeof (int);
-
- *((int *) data->text) = size;
-
- return buf_send_output (buf);
-}
-
-/* Append a list of buffer_data structures to an buffer. */
-
-static inline void
-buf_append_data (buf, data, last)
- struct buffer *buf;
- struct buffer_data *data;
- struct buffer_data *last;
-{
- if (data != NULL)
- {
- if (buf->data == NULL)
- buf->data = data;
- else
- buf->last->next = data;
- buf->last = last;
- }
-}
-
-/*
- * Copy the contents of file F into buffer_data structures. We can't
- * copy directly into an buffer, because we want to handle failure and
- * succeess differently. Returns 0 on success, or -2 if out of
- * memory, or a status code on error. Since the caller happens to
- * know the size of the file, it is passed in as SIZE. On success,
- * this function sets *RETP and *LASTP, which may be passed to
- * buf_append_data.
- */
-
-static int
-buf_read_file (f, size, retp, lastp)
- FILE *f;
- long size;
- struct buffer_data **retp;
- struct buffer_data **lastp;
-{
- int status;
-
- *retp = NULL;
- *lastp = NULL;
-
- while (size > 0)
- {
- struct buffer_data *data;
- int get;
-
- data = get_buffer_data ();
- if (data == NULL)
- {
- status = -2;
- goto error_return;
- }
-
- if (*retp == NULL)
- *retp = data;
- else
- (*lastp)->next = data;
- data->next = NULL;
- *lastp = data;
-
- data->bufp = data->text;
- data->size = 0;
-
- if (size > BUFFER_DATA_SIZE)
- get = BUFFER_DATA_SIZE;
- else
- get = size;
-
- errno = EIO;
- if (fread (data->text, get, 1, f) != 1)
- {
- status = errno;
- goto error_return;
- }
-
- data->size += get;
- size -= get;
- }
-
- return 0;
-
- error_return:
- if (*retp != NULL)
- {
- (*lastp)->next = free_buffer_data;
- free_buffer_data = *retp;
- }
- return status;
-}
-
-static int
-buf_read_file_to_eof (f, retp, lastp)
- FILE *f;
- struct buffer_data **retp;
- struct buffer_data **lastp;
-{
- int status;
-
- *retp = NULL;
- *lastp = NULL;
-
- while (!feof (f))
- {
- struct buffer_data *data;
- int get, nread;
-
- data = get_buffer_data ();
- if (data == NULL)
- {
- status = -2;
- goto error_return;
- }
-
- if (*retp == NULL)
- *retp = data;
- else
- (*lastp)->next = data;
- data->next = NULL;
- *lastp = data;
-
- data->bufp = data->text;
- data->size = 0;
-
- get = BUFFER_DATA_SIZE;
-
- errno = EIO;
- nread = fread (data->text, 1, get, f);
- if (nread == 0 && !feof (f))
- {
- status = errno;
- goto error_return;
- }
-
- data->size = nread;
- }
-
- return 0;
-
- error_return:
- if (*retp != NULL)
- {
- (*lastp)->next = free_buffer_data;
- free_buffer_data = *retp;
- }
- return status;
-}
-
-static int
-buf_chain_length (buf)
- struct buffer_data *buf;
-{
- int size = 0;
- while (buf)
- {
- size += buf->size;
- buf = buf->next;
- }
- return size;
-}
-
-/*
- * Read an arbitrary amount of data from a file descriptor into an
- * input buffer. The file descriptor will be in nonblocking mode, and
- * we just grab what we can. Return 0 on success, or -1 on end of
- * file, or -2 if out of memory, or an error code. If COUNTP is not
- * NULL, *COUNTP is set to the number of bytes read.
- */
-
-static int
-buf_input_data (buf, countp)
- struct buffer *buf;
- int *countp;
-{
- if (buf->output)
- abort ();
-
- if (countp != NULL)
- *countp = 0;
-
- while (1)
- {
- int get;
- int nbytes;
-
- if (buf->data == NULL
- || (buf->last->bufp + buf->last->size
- == buf->last->text + BUFFER_DATA_SIZE))
- {
- struct buffer_data *data;
- data = get_buffer_data ();
- if (data == NULL)
- {
- (*buf->memory_error) (buf);
- return -2;
- }
-
- if (buf->data == NULL)
- buf->data = data;
- else
- buf->last->next = data;
- data->next = NULL;
- buf->last = data;
-
- data->bufp = data->text;
- data->size = 0;
- }
-
- get = ((buf->last->text + BUFFER_DATA_SIZE)
- - (buf->last->bufp + buf->last->size));
- nbytes = read (buf->fd, buf->last->bufp + buf->last->size, get);
- if (nbytes <= 0)
- {
- if (nbytes == 0)
- {
- /*
- * This assumes that we are using POSIX or BSD style
- * nonblocking I/O. On System V we will get a zero
- * return if there is no data, even when not at EOF.
- */
- return -1;
- }
-
- if (errno == EAGAIN
-#ifdef EWOULDBLOCK
- || errno == EWOULDBLOCK
-#endif
- )
- return 0;
-
- return errno;
- }
-
- buf->last->size += nbytes;
- if (countp != NULL)
- *countp += nbytes;
- }
-
- /*NOTREACHED*/
-}
-
-/*
- * Copy lines from an input buffer to an output buffer. This copies
- * all complete lines (characters up to a newline) from INBUF to
- * OUTBUF. Each line in OUTBUF is preceded by the character COMMAND
- * and a space.
- */
-
-static void
-buf_copy_lines (outbuf, inbuf, command)
- struct buffer *outbuf;
- struct buffer *inbuf;
- int command;
-{
- if (! outbuf->output || inbuf->output)
- abort ();
-
- while (1)
- {
- struct buffer_data *data;
- struct buffer_data *nldata;
- char *nl;
- int len;
-
- /* See if there is a newline in INBUF. */
- nldata = NULL;
- nl = NULL;
- for (data = inbuf->data; data != NULL; data = data->next)
- {
- nl = memchr (data->bufp, '\n', data->size);
- if (nl != NULL)
- {
- nldata = data;
- break;
- }
- }
-
- if (nldata == NULL)
- {
- /* There are no more lines in INBUF. */
- return;
- }
-
- /* Put in the command. */
- buf_append_char (outbuf, command);
- buf_append_char (outbuf, ' ');
-
- if (inbuf->data != nldata)
- {
- /*
- * Simply move over all the buffers up to the one containing
- * the newline.
- */
- for (data = inbuf->data; data->next != nldata; data = data->next)
- ;
- data->next = NULL;
- buf_append_data (outbuf, inbuf->data, data);
- inbuf->data = nldata;
- }
-
- /*
- * If the newline is at the very end of the buffer, just move
- * the buffer onto OUTBUF. Otherwise we must copy the data.
- */
- len = nl + 1 - nldata->bufp;
- if (len == nldata->size)
- {
- inbuf->data = nldata->next;
- if (inbuf->data == NULL)
- inbuf->last = NULL;
-
- nldata->next = NULL;
- buf_append_data (outbuf, nldata, nldata);
- }
- else
- {
- buf_output (outbuf, nldata->bufp, len);
- nldata->bufp += len;
- nldata->size -= len;
- }
- }
-}
-
-/*
- * Copy counted data from one buffer to another. The count is an
- * integer, host size, host byte order (it is only used across a
- * pipe). If there is enough data, it should be moved over. If there
- * is not enough data, it should remain on the original buffer. This
- * returns the number of bytes it needs to see in order to actually
- * copy something over.
- */
-
-static int
-buf_copy_counted (outbuf, inbuf)
- struct buffer *outbuf;
- struct buffer *inbuf;
-{
- if (! outbuf->output || inbuf->output)
- abort ();
-
- while (1)
- {
- struct buffer_data *data;
- int need;
- union
- {
- char intbuf[sizeof (int)];
- int i;
- } u;
- char *intp;
- int count;
- struct buffer_data *start;
- int startoff;
- struct buffer_data *stop;
- int stopwant;
-
- /* See if we have enough bytes to figure out the count. */
- need = sizeof (int);
- intp = u.intbuf;
- for (data = inbuf->data; data != NULL; data = data->next)
- {
- if (data->size >= need)
- {
- memcpy (intp, data->bufp, need);
- break;
- }
- memcpy (intp, data->bufp, data->size);
- intp += data->size;
- need -= data->size;
- }
- if (data == NULL)
- {
- /* We don't have enough bytes to form an integer. */
- return need;
- }
-
- count = u.i;
- start = data;
- startoff = need;
-
- /*
- * We have an integer in COUNT. We have gotten all the data
- * from INBUF in all buffers before START, and we have gotten
- * STARTOFF bytes from START. See if we have enough bytes
- * remaining in INBUF.
- */
- need = count - (start->size - startoff);
- if (need <= 0)
- {
- stop = start;
- stopwant = count;
- }
- else
- {
- for (data = start->next; data != NULL; data = data->next)
- {
- if (need <= data->size)
- break;
- need -= data->size;
- }
- if (data == NULL)
- {
- /* We don't have enough bytes. */
- return need;
- }
- stop = data;
- stopwant = need;
- }
-
- /*
- * We have enough bytes. Free any buffers in INBUF before
- * START, and remove STARTOFF bytes from START, so that we can
- * forget about STARTOFF.
- */
- start->bufp += startoff;
- start->size -= startoff;
-
- if (start->size == 0)
- start = start->next;
-
- if (stop->size == stopwant)
- {
- stop = stop->next;
- stopwant = 0;
- }
-
- while (inbuf->data != start)
- {
- data = inbuf->data;
- inbuf->data = data->next;
- data->next = free_buffer_data;
- free_buffer_data = data;
- }
-
- /*
- * We want to copy over the bytes from START through STOP. We
- * only want STOPWANT bytes from STOP.
- */
-
- if (start != stop)
- {
- /* Attach the buffers from START through STOP to OUTBUF. */
- for (data = start; data->next != stop; data = data->next)
- ;
- inbuf->data = stop;
- data->next = NULL;
- buf_append_data (outbuf, start, data);
- }
-
- if (stopwant > 0)
- {
- buf_output (outbuf, stop->bufp, stopwant);
- stop->bufp += stopwant;
- stop->size -= stopwant;
- }
- }
-
- /*NOTREACHED*/
-}
+#endif /* SERVER_FLOWCONTROL */
-/* While processing requests, this buffer accumulates data to be sent to
- the client, and then once we are in do_cvs_command, we use it
- for all the data to be sent. */
-static struct buffer buf_to_net;
-
static void serve_questionable PROTO((char *));
static void
@@ -2170,7 +1574,7 @@ serve_questionable (arg)
if (dir_name == NULL)
{
- buf_output0 (&buf_to_net, "E Protocol error: 'Directory' missing");
+ buf_output0 (buf_to_net, "E Protocol error: 'Directory' missing");
return;
}
@@ -2178,15 +1582,15 @@ serve_questionable (arg)
{
char *update_dir;
- buf_output (&buf_to_net, "M ? ", 4);
+ buf_output (buf_to_net, "M ? ", 4);
update_dir = dir_name + strlen (server_temp_dir) + 1;
if (!(update_dir[0] == '.' && update_dir[1] == '\0'))
{
- buf_output0 (&buf_to_net, update_dir);
- buf_output (&buf_to_net, "/", 1);
+ buf_output0 (buf_to_net, update_dir);
+ buf_output (buf_to_net, "/", 1);
}
- buf_output0 (&buf_to_net, arg);
- buf_output (&buf_to_net, "\n", 1);
+ buf_output0 (buf_to_net, arg);
+ buf_output (buf_to_net, "\n", 1);
}
}
@@ -2199,14 +1603,14 @@ serve_case (arg)
ign_case = 1;
}
-static struct buffer protocol;
+static struct buffer *protocol;
/* This is the output which we are saving up to send to the server, in the
child process. We will push it through, via the `protocol' buffer, when
we have a complete line. */
-static struct buffer saved_output;
+static struct buffer *saved_output;
/* Likewise, but stuff which will go to stderr. */
-static struct buffer saved_outerr;
+static struct buffer *saved_outerr;
static void
protocol_memory_error (buf)
@@ -2330,13 +1734,29 @@ do_cvs_command (command)
set_nonblock_fd (flowcontrol_pipe[1]);
#endif /* SERVER_FLOWCONTROL */
- dev_null_fd = open ("/dev/null", O_RDONLY);
+ dev_null_fd = CVS_OPEN ("/dev/null", O_RDONLY);
if (dev_null_fd < 0)
{
print_error (errno);
goto error_exit;
}
+ /* We shouldn't have any partial lines from cvs_output and
+ cvs_outerr, but we handle them here in case there is a bug. */
+ if (! buf_empty_p (saved_output))
+ {
+ buf_append_char (saved_output, '\n');
+ buf_copy_lines (buf_to_net, saved_output, 'M');
+ }
+ if (! buf_empty_p (saved_outerr))
+ {
+ buf_append_char (saved_outerr, '\n');
+ buf_copy_lines (buf_to_net, saved_outerr, 'E');
+ }
+
+ /* Flush out any pending data. */
+ buf_flush (buf_to_net, 1);
+
/* Don't use vfork; we're not going to exec(). */
command_pid = fork ();
if (command_pid < 0)
@@ -2353,18 +1773,20 @@ do_cvs_command (command)
flag. */
error_use_protocol = 0;
- protocol.data = protocol.last = NULL;
- protocol.fd = protocol_pipe[1];
- protocol.output = 1;
- protocol.nonblocking = 0;
- protocol.memory_error = protocol_memory_error;
+ protocol = fd_buffer_initialize (protocol_pipe[1], 0,
+ protocol_memory_error);
+
+ /* At this point we should no longer be using buf_to_net and
+ buf_from_net. Instead, everything should go through
+ protocol. */
+ buf_to_net = NULL;
+ buf_from_net = NULL;
- saved_output.data = saved_output.last = NULL;
- saved_output.fd = -1;
- saved_output.output = 0;
- saved_output.nonblocking = 0;
- saved_output.memory_error = protocol_memory_error;
- saved_outerr = saved_output;
+ /* These were originally set up to use outbuf_memory_error.
+ Since we're now in the child, we should use the simpler
+ protocol_memory_error function. */
+ saved_output->memory_error = protocol_memory_error;
+ saved_outerr->memory_error = protocol_memory_error;
if (dup2 (dev_null_fd, STDIN_FILENO) < 0)
error (1, errno, "can't set up pipes");
@@ -2400,9 +1822,9 @@ do_cvs_command (command)
/* OK, sit around getting all the input from the child. */
{
- struct buffer stdoutbuf;
- struct buffer stderrbuf;
- struct buffer protocol_inbuf;
+ struct buffer *stdoutbuf;
+ struct buffer *stderrbuf;
+ struct buffer *protocol_inbuf;
/* Number of file descriptors to check in select (). */
int num_to_check;
int count_needed = 0;
@@ -2429,32 +1851,25 @@ do_cvs_command (command)
++num_to_check;
if (num_to_check > FD_SETSIZE)
{
- printf ("E internal error: FD_SETSIZE not big enough.\nerror \n");
+ buf_output0 (buf_to_net,
+ "E internal error: FD_SETSIZE not big enough.\n\
+error \n");
goto error_exit;
}
- stdoutbuf.data = stdoutbuf.last = NULL;
- stdoutbuf.fd = stdout_pipe[0];
- stdoutbuf.output = 0;
- stdoutbuf.nonblocking = 0;
- stdoutbuf.memory_error = input_memory_error;
-
- stderrbuf.data = stderrbuf.last = NULL;
- stderrbuf.fd = stderr_pipe[0];
- stderrbuf.output = 0;
- stderrbuf.nonblocking = 0;
- stderrbuf.memory_error = input_memory_error;
-
- protocol_inbuf.data = protocol_inbuf.last = NULL;
- protocol_inbuf.fd = protocol_pipe[0];
- protocol_inbuf.output = 0;
- protocol_inbuf.nonblocking = 0;
- protocol_inbuf.memory_error = input_memory_error;
-
- set_nonblock (&buf_to_net);
- set_nonblock (&stdoutbuf);
- set_nonblock (&stderrbuf);
- set_nonblock (&protocol_inbuf);
+ stdoutbuf = fd_buffer_initialize (stdout_pipe[0], 1,
+ input_memory_error);
+
+ stderrbuf = fd_buffer_initialize (stderr_pipe[0], 1,
+ input_memory_error);
+
+ protocol_inbuf = fd_buffer_initialize (protocol_pipe[0], 1,
+ input_memory_error);
+
+ set_nonblock (buf_to_net);
+ set_nonblock (stdoutbuf);
+ set_nonblock (stderrbuf);
+ set_nonblock (protocol_inbuf);
if (close (stdout_pipe[1]) < 0)
{
@@ -2507,7 +1922,7 @@ do_cvs_command (command)
* See if we are swamping the remote client and filling our VM.
* Tell child to hold off if we do.
*/
- bufmemsize = buf_count_mem (&buf_to_net);
+ bufmemsize = buf_count_mem (buf_to_net);
if (!have_flowcontrolled && (bufmemsize > SERVER_HI_WATER))
{
if (write(flowcontrol_pipe[1], "S", 1) == 1)
@@ -2522,7 +1937,7 @@ do_cvs_command (command)
FD_ZERO (&readfds);
FD_ZERO (&writefds);
- if (! buf_empty_p (&buf_to_net))
+ if (! buf_empty_p (buf_to_net))
FD_SET (STDOUT_FILENO, &writefds);
if (stdout_pipe[0] >= 0)
@@ -2538,6 +1953,14 @@ do_cvs_command (command)
FD_SET (protocol_pipe[0], &readfds);
}
+ /* This process of selecting on the three pipes means that
+ we might not get output in the same order in which it
+ was written, thus producing the well-known
+ "out-of-order" bug. If the child process uses
+ cvs_output and cvs_outerr, it will send everything on
+ the protocol_pipe and avoid this problem, so the
+ solution is to use cvs_output and cvs_outerr in the
+ child process. */
do {
/* This used to select on exceptions too, but as far
as I know there was never any reason to do that and
@@ -2555,7 +1978,7 @@ do_cvs_command (command)
if (FD_ISSET (STDOUT_FILENO, &writefds))
{
/* What should we do with errors? syslog() them? */
- buf_send_output (&buf_to_net);
+ buf_send_output (buf_to_net);
}
if (stdout_pipe[0] >= 0
@@ -2563,9 +1986,9 @@ do_cvs_command (command)
{
int status;
- status = buf_input_data (&stdoutbuf, (int *) NULL);
+ status = buf_input_data (stdoutbuf, (int *) NULL);
- buf_copy_lines (&buf_to_net, &stdoutbuf, 'M');
+ buf_copy_lines (buf_to_net, stdoutbuf, 'M');
if (status == -1)
stdout_pipe[0] = -1;
@@ -2576,7 +1999,7 @@ do_cvs_command (command)
}
/* What should we do with errors? syslog() them? */
- buf_send_output (&buf_to_net);
+ buf_send_output (buf_to_net);
}
if (stderr_pipe[0] >= 0
@@ -2584,9 +2007,9 @@ do_cvs_command (command)
{
int status;
- status = buf_input_data (&stderrbuf, (int *) NULL);
+ status = buf_input_data (stderrbuf, (int *) NULL);
- buf_copy_lines (&buf_to_net, &stderrbuf, 'E');
+ buf_copy_lines (buf_to_net, stderrbuf, 'E');
if (status == -1)
stderr_pipe[0] = -1;
@@ -2597,7 +2020,7 @@ do_cvs_command (command)
}
/* What should we do with errors? syslog() them? */
- buf_send_output (&buf_to_net);
+ buf_send_output (buf_to_net);
}
if (protocol_pipe[0] >= 0
@@ -2605,8 +2028,17 @@ do_cvs_command (command)
{
int status;
int count_read;
+ int special;
- status = buf_input_data (&protocol_inbuf, &count_read);
+ status = buf_input_data (protocol_inbuf, &count_read);
+
+ if (status == -1)
+ protocol_pipe[0] = -1;
+ else if (status > 0)
+ {
+ print_error (status);
+ goto error_exit;
+ }
/*
* We only call buf_copy_counted if we have read
@@ -2615,20 +2047,30 @@ do_cvs_command (command)
* have.
*/
count_needed -= count_read;
- if (count_needed <= 0)
- count_needed = buf_copy_counted (&buf_to_net,
- &protocol_inbuf);
-
- if (status == -1)
- protocol_pipe[0] = -1;
- else if (status > 0)
+ while (count_needed <= 0)
{
- print_error (status);
- goto error_exit;
- }
+ count_needed = buf_copy_counted (buf_to_net,
+ protocol_inbuf,
+ &special);
+
+ /* What should we do with errors? syslog() them? */
+ buf_send_output (buf_to_net);
+
+ /* If SPECIAL got set to -1, it means that the child
+ wants us to flush the pipe. We don't want to block
+ on the network, but we flush what we can. If the
+ client supports the 'F' command, we send it. */
+ if (special == -1)
+ {
+ if (supported_response ("F"))
+ {
+ buf_append_char (buf_to_net, 'F');
+ buf_append_char (buf_to_net, '\n');
+ }
- /* What should we do with errors? syslog() them? */
- buf_send_output (&buf_to_net);
+ cvs_flusherr ();
+ }
+ }
}
}
@@ -2637,18 +2079,18 @@ do_cvs_command (command)
* anything left on stdoutbuf or stderrbuf (this could only
* happen if there was no trailing newline), send it over.
*/
- if (! buf_empty_p (&stdoutbuf))
+ if (! buf_empty_p (stdoutbuf))
{
- buf_append_char (&stdoutbuf, '\n');
- buf_copy_lines (&buf_to_net, &stdoutbuf, 'M');
+ buf_append_char (stdoutbuf, '\n');
+ buf_copy_lines (buf_to_net, stdoutbuf, 'M');
}
- if (! buf_empty_p (&stderrbuf))
+ if (! buf_empty_p (stderrbuf))
{
- buf_append_char (&stderrbuf, '\n');
- buf_copy_lines (&buf_to_net, &stderrbuf, 'E');
+ buf_append_char (stderrbuf, '\n');
+ buf_copy_lines (buf_to_net, stderrbuf, 'E');
}
- if (! buf_empty_p (&protocol_inbuf))
- buf_output0 (&buf_to_net,
+ if (! buf_empty_p (protocol_inbuf))
+ buf_output0 (buf_to_net,
"E Protocol error: uncounted data discarded\n");
errs = 0;
@@ -2672,6 +2114,7 @@ do_cvs_command (command)
else
{
int sig = WTERMSIG (status);
+ char buf[50];
/*
* This is really evil, because signals might be numbered
* differently on the two systems. We should be using
@@ -2679,14 +2122,17 @@ do_cvs_command (command)
* variety). But cvs doesn't currently use libiberty...we
* could roll our own.... FIXME.
*/
- printf ("E Terminated with fatal signal %d\n", sig);
+ buf_output0 (buf_to_net, "E Terminated with fatal signal ");
+ sprintf (buf, "%d\n", sig);
+ buf_output0 (buf_to_net, buf);
/* Test for a core dump. Is this portable? */
if (status & 0x80)
{
- printf ("E Core dumped; preserving %s on server.\n\
-E CVS locks may need cleaning up.\n",
- server_temp_dir);
+ buf_output0 (buf_to_net, "E Core dumped; preserving ");
+ buf_output0 (buf_to_net, orig_server_temp_dir);
+ buf_output0 (buf_to_net, " on server.\n\
+E CVS locks may need cleaning up.\n");
dont_delete_temp = 1;
}
++errs;
@@ -2699,15 +2145,15 @@ E CVS locks may need cleaning up.\n",
* OK, we've waited for the child. By now all CVS locks are free
* and it's OK to block on the network.
*/
- set_block (&buf_to_net);
- buf_send_output (&buf_to_net);
+ set_block (buf_to_net);
+ buf_flush (buf_to_net, 1);
}
if (errs)
/* We will have printed an error message already. */
- printf ("error \n");
+ buf_output0 (buf_to_net, "error \n");
else
- printf ("ok\n");
+ buf_output0 (buf_to_net, "ok\n");
goto free_args_and_return;
error_exit:
@@ -2744,6 +2190,11 @@ E CVS locks may need cleaning up.\n",
argument_count = 1;
}
+
+ /* Flush out any data not yet sent. */
+ set_block (buf_to_net);
+ buf_flush (buf_to_net, 1);
+
return;
}
@@ -2789,7 +2240,9 @@ server_pause_check()
if (FD_ISSET (flowcontrol_pipe[0], &fds))
{
- while ((n = read (flowcontrol_pipe[0], buf, 1) == 1))
+ int got;
+
+ while ((got = read (flowcontrol_pipe[0], buf, 1)) == 1)
{
if (*buf == 'S') /* Stop */
paused = 1;
@@ -2798,8 +2251,16 @@ server_pause_check()
else
return; /* ??? */
}
- if (n == 0)
- paused = 0; /* other end died */
+
+ /* This assumes that we are using BSD or POSIX nonblocking
+ I/O. System V nonblocking I/O returns zero if there is
+ nothing to read. */
+ if (got == 0)
+ error (1, 0, "flow control EOF");
+ if (got < 0 && ! blocking_error (errno))
+ {
+ error (1, errno, "flow control read failed");
+ }
}
}
}
@@ -2815,13 +2276,13 @@ output_dir (update_dir, repository)
if (use_dir_and_repos)
{
if (update_dir[0] == '\0')
- buf_output0 (&protocol, ".");
+ buf_output0 (protocol, ".");
else
- buf_output0 (&protocol, update_dir);
- buf_output0 (&protocol, "/\n");
+ buf_output0 (protocol, update_dir);
+ buf_output0 (protocol, "/\n");
}
- buf_output0 (&protocol, repository);
- buf_output0 (&protocol, "/");
+ buf_output0 (protocol, repository);
+ buf_output0 (protocol, "/");
}
/*
@@ -2933,9 +2394,9 @@ server_scratch (fname)
if (scratched_file != NULL)
{
- buf_output0 (&protocol,
+ buf_output0 (protocol,
"E CVS server internal error: duplicate Scratch_Entry\n");
- buf_send_counted (&protocol);
+ buf_send_counted (protocol);
return;
}
scratched_file = xstrdup (fname);
@@ -2954,12 +2415,12 @@ new_entries_line ()
{
if (entries_line)
{
- buf_output0 (&protocol, entries_line);
- buf_output (&protocol, "\n", 1);
+ buf_output0 (protocol, entries_line);
+ buf_output (protocol, "\n", 1);
}
else
/* Return the error message as the Entries line. */
- buf_output0 (&protocol,
+ buf_output0 (protocol,
"CVS server internal error: Register missing\n");
free (entries_line);
entries_line = NULL;
@@ -2983,7 +2444,7 @@ checked_in_response (file, update_dir, repository)
struct stat sb;
char *mode_string;
- if (stat (file, &sb) < 0)
+ if ( CVS_STAT (file, &sb) < 0)
{
/* Not clear to me why the file would fail to exist, but it
was happening somewhere in the testsuite. */
@@ -2992,18 +2453,18 @@ checked_in_response (file, update_dir, repository)
}
else
{
- buf_output0 (&protocol, "Mode ");
+ buf_output0 (protocol, "Mode ");
mode_string = mode_to_string (sb.st_mode);
- buf_output0 (&protocol, mode_string);
- buf_output0 (&protocol, "\n");
+ buf_output0 (protocol, mode_string);
+ buf_output0 (protocol, "\n");
free (mode_string);
}
}
- buf_output0 (&protocol, "Checked-in ");
+ buf_output0 (protocol, "Checked-in ");
output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
+ buf_output0 (protocol, file);
+ buf_output (protocol, "\n", 1);
new_entries_line ();
}
@@ -3021,10 +2482,10 @@ server_checked_in (file, update_dir, repository)
* This happens if we are now doing a "cvs remove" after a previous
* "cvs add" (without a "cvs ci" in between).
*/
- buf_output0 (&protocol, "Remove-entry ");
+ buf_output0 (protocol, "Remove-entry ");
output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
+ buf_output0 (protocol, file);
+ buf_output (protocol, "\n", 1);
free (scratched_file);
scratched_file = NULL;
}
@@ -3032,7 +2493,7 @@ server_checked_in (file, update_dir, repository)
{
checked_in_response (file, update_dir, repository);
}
- buf_send_counted (&protocol);
+ buf_send_counted (protocol);
}
void
@@ -3050,14 +2511,14 @@ server_update_entries (file, update_dir, repository, updated)
{
if (!supported_response ("New-entry"))
return;
- buf_output0 (&protocol, "New-entry ");
+ buf_output0 (protocol, "New-entry ");
output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
+ buf_output0 (protocol, file);
+ buf_output (protocol, "\n", 1);
new_entries_line ();
}
- buf_send_counted (&protocol);
+ buf_send_counted (protocol);
}
static void
@@ -3230,13 +2691,7 @@ static void
serve_init (arg)
char *arg;
{
- CVSroot = malloc (strlen (arg) + 1);
- if (CVSroot == NULL)
- {
- pending_error = ENOMEM;
- return;
- }
- strcpy (CVSroot, arg);
+ set_local_cvsroot (arg);
do_cvs_command (init);
}
@@ -3269,7 +2724,7 @@ serve_co (arg)
tempdir = malloc (strlen (server_temp_dir) + 80);
if (tempdir == NULL)
{
- printf ("E Out of memory\n");
+ buf_output0 (buf_to_net, "E Out of memory\n");
return;
}
strcpy (tempdir, server_temp_dir);
@@ -3277,15 +2732,19 @@ serve_co (arg)
status = mkdir_p (tempdir);
if (status != 0 && status != EEXIST)
{
- printf ("E Cannot create %s\n", tempdir);
+ buf_output0 (buf_to_net, "E Cannot create ");
+ buf_output0 (buf_to_net, tempdir);
+ buf_append_char (buf_to_net, '\n');
print_error (errno);
free (tempdir);
return;
}
- if (chdir (tempdir) < 0)
+ if ( CVS_CHDIR (tempdir) < 0)
{
- printf ("E Cannot change to directory %s\n", tempdir);
+ buf_output0 (buf_to_net, "E Cannot change to directory ");
+ buf_output0 (buf_to_net, tempdir);
+ buf_append_char (buf_to_net, '\n');
print_error (errno);
free (tempdir);
return;
@@ -3313,34 +2772,27 @@ server_copy_file (file, update_dir, repository, newfile)
{
if (!supported_response ("Copy-file"))
return;
- buf_output0 (&protocol, "Copy-file ");
+ buf_output0 (protocol, "Copy-file ");
output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output0 (&protocol, "\n");
- buf_output0 (&protocol, newfile);
- buf_output0 (&protocol, "\n");
+ buf_output0 (protocol, file);
+ buf_output0 (protocol, "\n");
+ buf_output0 (protocol, newfile);
+ buf_output0 (protocol, "\n");
}
+/* See server.h for description. */
+
void
-server_updated (file, update_dir, repository, updated, file_info, checksum)
- char *file;
- char *update_dir;
- char *repository;
+server_updated (finfo, vers, updated, file_info, checksum)
+ struct file_info *finfo;
+ Vers_TS *vers;
enum server_updated_arg4 updated;
struct stat *file_info;
unsigned char *checksum;
{
- char *short_pathname;
-
if (noexec)
return;
- short_pathname = xmalloc (strlen (update_dir) + strlen (file) + 10);
- if (update_dir[0] == '\0')
- strcpy (short_pathname, file);
- else
- sprintf (short_pathname, "%s/%s", update_dir, file);
-
if (entries_line != NULL && scratched_file == NULL)
{
FILE *f;
@@ -3349,7 +2801,7 @@ server_updated (file, update_dir, repository, updated, file_info, checksum)
unsigned long size;
char size_text[80];
- if (stat (file, &sb) < 0)
+ if ( CVS_STAT (finfo->file, &sb) < 0)
{
if (existence_error (errno))
{
@@ -3357,13 +2809,12 @@ server_updated (file, update_dir, repository, updated, file_info, checksum)
* If we have a sticky tag for a branch on which the
* file is dead, and cvs update the directory, it gets
* a T_CHECKOUT but no file. So in this case just
- * forget the whole thing.
- */
+ * forget the whole thing. */
free (entries_line);
entries_line = NULL;
goto done;
}
- error (1, errno, "reading %s", short_pathname);
+ error (1, errno, "reading %s", finfo->fullname);
}
if (checksum != NULL)
@@ -3380,27 +2831,39 @@ server_updated (file, update_dir, repository, updated, file_info, checksum)
int i;
char buf[3];
- buf_output0 (&protocol, "Checksum ");
+ buf_output0 (protocol, "Checksum ");
for (i = 0; i < 16; i++)
{
sprintf (buf, "%02x", (unsigned int) checksum[i]);
- buf_output0 (&protocol, buf);
+ buf_output0 (protocol, buf);
}
- buf_append_char (&protocol, '\n');
+ buf_append_char (protocol, '\n');
}
}
if (updated == SERVER_UPDATED)
- buf_output0 (&protocol, "Updated ");
+ {
+ if (!(supported_response ("Created")
+ && supported_response ("Update-existing")))
+ buf_output0 (protocol, "Updated ");
+ else
+ {
+ assert (vers != NULL);
+ if (vers->ts_user == NULL)
+ buf_output0 (protocol, "Created ");
+ else
+ buf_output0 (protocol, "Update-existing ");
+ }
+ }
else if (updated == SERVER_MERGED)
- buf_output0 (&protocol, "Merged ");
+ buf_output0 (protocol, "Merged ");
else if (updated == SERVER_PATCHED)
- buf_output0 (&protocol, "Patched ");
+ buf_output0 (protocol, "Patched ");
else
abort ();
- output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
+ output_dir (finfo->update_dir, finfo->repository);
+ buf_output0 (protocol, finfo->file);
+ buf_output (protocol, "\n", 1);
new_entries_line ();
@@ -3415,8 +2878,8 @@ server_updated (file, update_dir, repository, updated, file_info, checksum)
mode_string = mode_to_string (file_info->st_mode);
else
mode_string = mode_to_string (sb.st_mode);
- buf_output0 (&protocol, mode_string);
- buf_output0 (&protocol, "\n");
+ buf_output0 (protocol, mode_string);
+ buf_output0 (protocol, "\n");
free (mode_string);
}
@@ -3428,7 +2891,7 @@ server_updated (file, update_dir, repository, updated, file_info, checksum)
file we are sending. The client handles any line ending
translation if necessary. */
- if (gzip_level
+ if (file_gzip_level
/*
* For really tiny files, the gzip process startup
* time will outweigh the compression savings. This
@@ -3440,51 +2903,51 @@ server_updated (file, update_dir, repository, updated, file_info, checksum)
int status, fd, gzip_status;
pid_t gzip_pid;
- fd = open (file, O_RDONLY | OPEN_BINARY, 0);
+ fd = CVS_OPEN (finfo->file, O_RDONLY | OPEN_BINARY, 0);
if (fd < 0)
- error (1, errno, "reading %s", short_pathname);
- fd = filter_through_gzip (fd, 1, gzip_level, &gzip_pid);
+ error (1, errno, "reading %s", finfo->fullname);
+ fd = filter_through_gzip (fd, 1, file_gzip_level, &gzip_pid);
f = fdopen (fd, "rb");
status = buf_read_file_to_eof (f, &list, &last);
size = buf_chain_length (list);
if (status == -2)
- (*protocol.memory_error) (&protocol);
+ (*protocol->memory_error) (protocol);
else if (status != 0)
error (1, ferror (f) ? errno : 0, "reading %s",
- short_pathname);
+ finfo->fullname);
if (fclose (f) == EOF)
- error (1, errno, "reading %s", short_pathname);
+ error (1, errno, "reading %s", finfo->fullname);
if (waitpid (gzip_pid, &gzip_status, 0) == -1)
error (1, errno, "waiting for gzip process %ld",
(long) gzip_pid);
else if (gzip_status != 0)
error (1, 0, "gzip exited %d", gzip_status);
/* Prepending length with "z" is flag for using gzip here. */
- buf_output0 (&protocol, "z");
+ buf_output0 (protocol, "z");
}
else
{
long status;
size = sb.st_size;
- f = fopen (file, "rb");
+ f = CVS_FOPEN (finfo->file, "rb");
if (f == NULL)
- error (1, errno, "reading %s", short_pathname);
+ error (1, errno, "reading %s", finfo->fullname);
status = buf_read_file (f, sb.st_size, &list, &last);
if (status == -2)
- (*protocol.memory_error) (&protocol);
+ (*protocol->memory_error) (protocol);
else if (status != 0)
error (1, ferror (f) ? errno : 0, "reading %s",
- short_pathname);
+ finfo->fullname);
if (fclose (f) == EOF)
- error (1, errno, "reading %s", short_pathname);
+ error (1, errno, "reading %s", finfo->fullname);
}
}
sprintf (size_text, "%lu\n", size);
- buf_output0 (&protocol, size_text);
+ buf_output0 (protocol, size_text);
- buf_append_data (&protocol, list, last);
+ buf_append_data (protocol, list, last);
/* Note we only send a newline here if the file ended with one. */
/*
@@ -3498,25 +2961,25 @@ server_updated (file, update_dir, repository, updated, file_info, checksum)
/* But if we are joining, we'll need the file when we call
join_file. */
&& !joining ())
- unlink (file);
+ CVS_UNLINK (finfo->file);
}
else if (scratched_file != NULL && entries_line == NULL)
{
- if (strcmp (scratched_file, file) != 0)
+ if (strcmp (scratched_file, finfo->file) != 0)
error (1, 0,
"CVS server internal error: `%s' vs. `%s' scratched",
scratched_file,
- file);
+ finfo->file);
free (scratched_file);
scratched_file = NULL;
if (kill_scratched_file)
- buf_output0 (&protocol, "Removed ");
+ buf_output0 (protocol, "Removed ");
else
- buf_output0 (&protocol, "Remove-entry ");
- output_dir (update_dir, repository);
- buf_output0 (&protocol, file);
- buf_output (&protocol, "\n", 1);
+ buf_output0 (protocol, "Remove-entry ");
+ output_dir (finfo->update_dir, finfo->repository);
+ buf_output0 (protocol, finfo->file);
+ buf_output (protocol, "\n", 1);
}
else if (scratched_file == NULL && entries_line == NULL)
{
@@ -3528,9 +2991,8 @@ server_updated (file, update_dir, repository, updated, file_info, checksum)
else
error (1, 0,
"CVS server internal error: Register *and* Scratch_Entry.\n");
- buf_send_counted (&protocol);
- done:
- free (short_pathname);
+ buf_send_counted (protocol);
+ done:;
}
void
@@ -3543,10 +3005,10 @@ server_set_entstat (update_dir, repository)
set_static_supported = supported_response ("Set-static-directory");
if (!set_static_supported) return;
- buf_output0 (&protocol, "Set-static-directory ");
+ buf_output0 (protocol, "Set-static-directory ");
output_dir (update_dir, repository);
- buf_output0 (&protocol, "\n");
- buf_send_counted (&protocol);
+ buf_output0 (protocol, "\n");
+ buf_send_counted (protocol);
}
void
@@ -3562,10 +3024,10 @@ server_clear_entstat (update_dir, repository)
if (noexec)
return;
- buf_output0 (&protocol, "Clear-static-directory ");
+ buf_output0 (protocol, "Clear-static-directory ");
output_dir (update_dir, repository);
- buf_output0 (&protocol, "\n");
- buf_send_counted (&protocol);
+ buf_output0 (protocol, "\n");
+ buf_send_counted (protocol);
}
void
@@ -3576,6 +3038,9 @@ server_set_sticky (update_dir, repository, tag, date)
char *date;
{
static int set_sticky_supported = -1;
+
+ assert (update_dir != NULL);
+
if (set_sticky_supported == -1)
set_sticky_supported = supported_response ("Set-sticky");
if (!set_sticky_supported) return;
@@ -3585,28 +3050,28 @@ server_set_sticky (update_dir, repository, tag, date)
if (tag == NULL && date == NULL)
{
- buf_output0 (&protocol, "Clear-sticky ");
+ buf_output0 (protocol, "Clear-sticky ");
output_dir (update_dir, repository);
- buf_output0 (&protocol, "\n");
+ buf_output0 (protocol, "\n");
}
else
{
- buf_output0 (&protocol, "Set-sticky ");
+ buf_output0 (protocol, "Set-sticky ");
output_dir (update_dir, repository);
- buf_output0 (&protocol, "\n");
+ buf_output0 (protocol, "\n");
if (tag != NULL)
{
- buf_output0 (&protocol, "T");
- buf_output0 (&protocol, tag);
+ buf_output0 (protocol, "T");
+ buf_output0 (protocol, tag);
}
else
{
- buf_output0 (&protocol, "D");
- buf_output0 (&protocol, date);
+ buf_output0 (protocol, "D");
+ buf_output0 (protocol, date);
}
- buf_output0 (&protocol, "\n");
+ buf_output0 (protocol, "\n");
}
- buf_send_counted (&protocol);
+ buf_send_counted (protocol);
}
struct template_proc_data
@@ -3633,11 +3098,11 @@ template_proc (repository, template)
if (!supported_response ("Template"))
/* Might want to warn the user that the rcsinfo feature won't work. */
return 0;
- buf_output0 (&protocol, "Template ");
+ buf_output0 (protocol, "Template ");
output_dir (data->update_dir, data->repository);
- buf_output0 (&protocol, "\n");
+ buf_output0 (protocol, "\n");
- fp = fopen (template, "rb");
+ fp = CVS_FOPEN (template, "rb");
if (fp == NULL)
{
error (0, errno, "Couldn't open rcsinfo template file %s", template);
@@ -3649,11 +3114,11 @@ template_proc (repository, template)
return 1;
}
sprintf (buf, "%ld\n", (long) sb.st_size);
- buf_output0 (&protocol, buf);
+ buf_output0 (protocol, buf);
while (!feof (fp))
{
n = fread (buf, 1, sizeof buf, fp);
- buf_output (&protocol, buf, n);
+ buf_output (protocol, buf, n);
if (ferror (fp))
{
error (0, errno, "cannot read rcsinfo template file %s", template);
@@ -3686,7 +3151,24 @@ serve_gzip_contents (arg)
level = atoi (arg);
if (level == 0)
level = 6;
- gzip_level = level;
+ file_gzip_level = level;
+}
+
+static void
+serve_gzip_stream (arg)
+ char *arg;
+{
+ int level;
+ level = atoi (arg);
+ if (level == 0)
+ level = 6;
+
+ /* All further communication with the client will be compressed. */
+
+ buf_to_net = compress_buffer_initialize (buf_to_net, 0, level,
+ buf_to_net->memory_error);
+ buf_from_net = compress_buffer_initialize (buf_from_net, 1, level,
+ buf_from_net->memory_error);
}
static void
@@ -3724,23 +3206,37 @@ expand_proc (pargc, argv, where, mwhere, mfile, shorten,
if (mwhere != NULL)
{
- printf ("Module-expansion %s", mwhere);
+ buf_output0 (buf_to_net, "Module-expansion ");
+ buf_output0 (buf_to_net, mwhere);
if (mfile != NULL)
{
- printf ("/%s", mfile);
+ buf_append_char (buf_to_net, '/');
+ buf_output0 (buf_to_net, mfile);
}
- printf ("\n");
+ buf_append_char (buf_to_net, '\n');
}
else
- {
+ {
/* We may not need to do this anymore -- check the definition
of aliases before removing */
if (*pargc == 1)
- printf ("Module-expansion %s\n", dir);
+ {
+ buf_output0 (buf_to_net, "Module-expansion ");
+ buf_output0 (buf_to_net, dir);
+ buf_append_char (buf_to_net, '\n');
+ }
else
- for (i = 1; i < *pargc; ++i)
- printf ("Module-expansion %s/%s\n", dir, argv[i]);
- }
+ {
+ for (i = 1; i < *pargc; ++i)
+ {
+ buf_output0 (buf_to_net, "Module-expansion ");
+ buf_output0 (buf_to_net, dir);
+ buf_append_char (buf_to_net, '/');
+ buf_output0 (buf_to_net, argv[i]);
+ buf_append_char (buf_to_net, '\n');
+ }
+ }
+ }
return 0;
}
@@ -3779,9 +3275,13 @@ serve_expand_modules (arg)
}
if (err)
/* We will have printed an error message already. */
- printf ("error \n");
+ buf_output0 (buf_to_net, "error \n");
else
- printf ("ok\n");
+ buf_output0 (buf_to_net, "ok\n");
+
+ /* The client is waiting for the module expansions, so we must
+ send the output now. */
+ buf_flush (buf_to_net, 1);
}
void
@@ -3792,20 +3292,23 @@ server_prog (dir, name, which)
{
if (!supported_response ("Set-checkin-prog"))
{
- printf ("E \
+ buf_output0 (buf_to_net, "E \
warning: this client does not support -i or -u flags in the modules file.\n");
return;
}
switch (which)
{
case PROG_CHECKIN:
- printf ("Set-checkin-prog ");
+ buf_output0 (buf_to_net, "Set-checkin-prog ");
break;
case PROG_UPDATE:
- printf ("Set-update-prog ");
+ buf_output0 (buf_to_net, "Set-update-prog ");
break;
}
- printf ("%s\n%s\n", dir, name);
+ buf_output0 (buf_to_net, dir);
+ buf_append_char (buf_to_net, '\n');
+ buf_output0 (buf_to_net, name);
+ buf_append_char (buf_to_net, '\n');
}
static void
@@ -3813,7 +3316,7 @@ serve_checkin_prog (arg)
char *arg;
{
FILE *f;
- f = fopen (CVSADM_CIPROG, "w+");
+ f = CVS_FOPEN (CVSADM_CIPROG, "w+");
if (f == NULL)
{
pending_error = errno;
@@ -3842,7 +3345,7 @@ serve_update_prog (arg)
char *arg;
{
FILE *f;
- f = fopen (CVSADM_UPROG, "w+");
+ f = CVS_FOPEN (CVSADM_UPROG, "w+");
if (f == NULL)
{
pending_error = errno;
@@ -3906,7 +3409,13 @@ struct request requests[] =
REQ_LINE("Argument", serve_argument, rq_essential),
REQ_LINE("Argumentx", serve_argumentx, rq_essential),
REQ_LINE("Global_option", serve_global_option, rq_optional),
+ REQ_LINE("Gzip-stream", serve_gzip_stream, rq_optional),
REQ_LINE("Set", serve_set, rq_optional),
+#ifdef ENCRYPTION
+#ifdef HAVE_KERBEROS
+ REQ_LINE("Kerberos-encrypt", serve_kerberos_encrypt, rq_optional),
+#endif
+#endif
REQ_LINE("expand-modules", serve_expand_modules, rq_optional),
REQ_LINE("ci", serve_ci, rq_essential),
REQ_LINE("co", serve_co, rq_essential),
@@ -3950,11 +3459,20 @@ serve_valid_requests (arg)
struct request *rq;
if (print_pending_error ())
return;
- printf ("Valid-requests");
+ buf_output0 (buf_to_net, "Valid-requests");
for (rq = requests; rq->name != NULL; rq++)
+ {
if (rq->func != NULL)
- printf (" %s", rq->name);
- printf ("\nok\n");
+ {
+ buf_append_char (buf_to_net, ' ');
+ buf_output0 (buf_to_net, rq->name);
+ }
+ }
+ buf_output0 (buf_to_net, "\nok\n");
+
+ /* The client is waiting for the list of valid requests, so we
+ must send the output now. */
+ buf_flush (buf_to_net, 1);
}
#ifdef sun
@@ -3966,10 +3484,10 @@ static int command_pid_is_dead;
static void wait_sig (sig)
int sig;
{
- int status;
- pid_t r = wait (&status);
- if (r == command_pid)
- command_pid_is_dead++;
+ int status;
+ pid_t r = wait (&status);
+ if (r == command_pid)
+ command_pid_is_dead++;
}
#endif
@@ -3978,104 +3496,135 @@ server_cleanup (sig)
int sig;
{
/* Do "rm -rf" on the temp directory. */
- int len;
- char *cmd;
- char *temp_dir;
+ int status;
+ int save_noexec;
+
+ if (buf_to_net != NULL)
+ {
+ /* FIXME: If this is not the final call from server, this
+ could deadlock, because the client might be blocked writing
+ to us. This should not be a problem in practice, because
+ we do not generate much output when the client is not
+ waiting for it. */
+ set_block (buf_to_net);
+ buf_flush (buf_to_net, 1);
+
+ /* The calls to buf_shutdown are currently only meaningful
+ when we are using compression. First we shut down
+ BUF_FROM_NET. That will pick up the checksum generated
+ when the client shuts down its buffer. Then, after we have
+ generated any final output, we shut down BUF_TO_NET. */
+
+ status = buf_shutdown (buf_from_net);
+ if (status != 0)
+ {
+ error (0, status, "shutting down buffer from client");
+ buf_flush (buf_to_net, 1);
+ }
+ }
if (dont_delete_temp)
+ {
+ if (buf_to_net != NULL)
+ (void) buf_shutdown (buf_to_net);
return;
+ }
/* What a bogus kludge. This disgusting code makes all kinds of
assumptions about SunOS, and is only for a bug in that system.
So only enable it on Suns. */
#ifdef sun
- if (command_pid > 0) {
- /* To avoid crashes on SunOS due to bugs in SunOS tmpfs
- triggered by the use of rename() in RCS, wait for the
- subprocess to die. Unfortunately, this means draining output
- while waiting for it to unblock the signal we sent it. Yuck! */
- int status;
- pid_t r;
-
- signal (SIGCHLD, wait_sig);
- if (sig)
- /* Perhaps SIGTERM would be more correct. But the child
- process will delay the SIGINT delivery until its own
- children have exited. */
- kill (command_pid, SIGINT);
- /* The caller may also have sent a signal to command_pid, so
- always try waiting. First, though, check and see if it's still
- there.... */
+ if (command_pid > 0)
+ {
+ /* To avoid crashes on SunOS due to bugs in SunOS tmpfs
+ triggered by the use of rename() in RCS, wait for the
+ subprocess to die. Unfortunately, this means draining output
+ while waiting for it to unblock the signal we sent it. Yuck! */
+ int status;
+ pid_t r;
+
+ signal (SIGCHLD, wait_sig);
+ if (sig)
+ /* Perhaps SIGTERM would be more correct. But the child
+ process will delay the SIGINT delivery until its own
+ children have exited. */
+ kill (command_pid, SIGINT);
+ /* The caller may also have sent a signal to command_pid, so
+ always try waiting. First, though, check and see if it's still
+ there.... */
do_waitpid:
- r = waitpid (command_pid, &status, WNOHANG);
- if (r == 0)
- ;
- else if (r == command_pid)
- command_pid_is_dead++;
- else if (r == -1)
- switch (errno) {
- case ECHILD:
- command_pid_is_dead++;
- break;
- case EINTR:
- goto do_waitpid;
- }
- else
- /* waitpid should always return one of the above values */
- abort ();
- while (!command_pid_is_dead) {
- struct timeval timeout;
- struct fd_set_wrapper readfds;
- char buf[100];
- int i;
-
- /* Use a non-zero timeout to avoid eating up CPU cycles. */
- timeout.tv_sec = 2;
- timeout.tv_usec = 0;
- readfds = command_fds_to_drain;
- switch (select (max_command_fd + 1, &readfds.fds,
- (fd_set *)0, (fd_set *)0,
- &timeout)) {
- case -1:
- if (errno != EINTR)
+ r = waitpid (command_pid, &status, WNOHANG);
+ if (r == 0)
+ ;
+ else if (r == command_pid)
+ command_pid_is_dead++;
+ else if (r == -1)
+ switch (errno)
+ {
+ case ECHILD:
+ command_pid_is_dead++;
+ break;
+ case EINTR:
+ goto do_waitpid;
+ }
+ else
+ /* waitpid should always return one of the above values */
abort ();
- case 0:
- /* timeout */
- break;
- case 1:
- for (i = 0; i <= max_command_fd; i++)
+ while (!command_pid_is_dead)
+ {
+ struct timeval timeout;
+ struct fd_set_wrapper readfds;
+ char buf[100];
+ int i;
+
+ /* Use a non-zero timeout to avoid eating up CPU cycles. */
+ timeout.tv_sec = 2;
+ timeout.tv_usec = 0;
+ readfds = command_fds_to_drain;
+ switch (select (max_command_fd + 1, &readfds.fds,
+ (fd_set *)0, (fd_set *)0,
+ &timeout))
{
- if (!FD_ISSET (i, &readfds.fds))
- continue;
- /* this fd is non-blocking */
- while (read (i, buf, sizeof (buf)) >= 1)
- ;
+ case -1:
+ if (errno != EINTR)
+ abort ();
+ case 0:
+ /* timeout */
+ break;
+ case 1:
+ for (i = 0; i <= max_command_fd; i++)
+ {
+ if (!FD_ISSET (i, &readfds.fds))
+ continue;
+ /* this fd is non-blocking */
+ while (read (i, buf, sizeof (buf)) >= 1)
+ ;
+ }
+ break;
+ default:
+ abort ();
}
- break;
- default:
- abort ();
}
- }
}
#endif
- /* This might be set by the user in ~/.bashrc, ~/.cshrc, etc. */
- temp_dir = getenv ("TMPDIR");
- if (temp_dir == NULL || temp_dir[0] == '\0')
- temp_dir = "/tmp";
- chdir(temp_dir);
-
- len = strlen (server_temp_dir) + 80;
- cmd = malloc (len);
- if (cmd == NULL)
- {
- printf ("E Cannot delete %s on server; out of memory\n",
- server_temp_dir);
- return;
- }
- sprintf (cmd, "rm -rf %s", server_temp_dir);
- system (cmd);
- free (cmd);
+ CVS_CHDIR (Tmpdir);
+ /* Temporarily clear noexec, so that we clean up our temp directory
+ regardless of it (this could more cleanly be handled by moving
+ the noexec check to all the unlink_file_dir callers from
+ unlink_file_dir itself). */
+ save_noexec = noexec;
+ noexec = 0;
+ /* FIXME? Would be nice to not ignore errors. But what should we do?
+ We could try to do this before we shut down the network connection,
+ and try to notify the client (but the client might not be waiting
+ for responses). We could try something like syslog() or our own
+ log file. */
+ unlink_file_dir (orig_server_temp_dir);
+ noexec = save_noexec;
+
+ if (buf_to_net != NULL)
+ (void) buf_shutdown (buf_to_net);
}
int server_active = 0;
@@ -4098,6 +3647,13 @@ server (argc, argv)
}
/* Ignore argc and argv. They might be from .cvsrc. */
+ buf_to_net = fd_buffer_initialize (STDOUT_FILENO, 0,
+ outbuf_memory_error);
+ buf_from_net = stdio_buffer_initialize (stdin, 1, outbuf_memory_error);
+
+ saved_output = buf_nonio_initialize (outbuf_memory_error);
+ saved_outerr = buf_nonio_initialize (outbuf_memory_error);
+
/* Since we're in the server parent process, error should use the
protocol to report error messages. */
error_use_protocol = 1;
@@ -4139,38 +3695,58 @@ error ENOMEM Virtual memory exhausted.\n");
{
char *p;
- /* This might be set by the user in ~/.bashrc, ~/.cshrc, etc. */
- char *temp_dir = getenv ("TMPDIR");
- if (temp_dir == NULL || temp_dir[0] == '\0')
- temp_dir = "/tmp";
-
- server_temp_dir = malloc (strlen (temp_dir) + 80);
- if (server_temp_dir == NULL)
+ /* The code which wants to chdir into server_temp_dir is not set
+ up to deal with it being a relative path. So give an error
+ for that case. */
+ if (!isabsolute (Tmpdir))
{
- /*
- * Strictly speaking, we're not supposed to output anything
- * now. But we're about to exit(), give it a try.
- */
- printf ("E Fatal server error, aborting.\n\
-error ENOMEM Virtual memory exhausted.\n");
- exit (EXIT_FAILURE);
+ pending_error_text = malloc (80 + strlen (Tmpdir));
+ if (pending_error_text == NULL)
+ {
+ pending_error = ENOMEM;
+ }
+ else
+ {
+ sprintf (pending_error_text,
+ "E Value of %s for TMPDIR is not absolute", Tmpdir);
+ }
+ /* FIXME: we would like this error to be persistent, that
+ is, not cleared by print_pending_error. The current client
+ will exit as soon as it gets an error, but the protocol spec
+ does not require a client to do so. */
}
- strcpy (server_temp_dir, temp_dir);
+ else
+ {
+ server_temp_dir = malloc (strlen (Tmpdir) + 80);
+ if (server_temp_dir == NULL)
+ {
+ /*
+ * Strictly speaking, we're not supposed to output anything
+ * now. But we're about to exit(), give it a try.
+ */
+ printf ("E Fatal server error, aborting.\n\
+error ENOMEM Virtual memory exhausted.\n");
+ exit (EXIT_FAILURE);
+ }
+ strcpy (server_temp_dir, Tmpdir);
- /* Remove a trailing slash from TMPDIR if present. */
- p = server_temp_dir + strlen (server_temp_dir) - 1;
- if (*p == '/')
- *p = '\0';
+ /* Remove a trailing slash from TMPDIR if present. */
+ p = server_temp_dir + strlen (server_temp_dir) - 1;
+ if (*p == '/')
+ *p = '\0';
- /*
- * I wanted to use cvs-serv/PID, but then you have to worry about
- * the permissions on the cvs-serv directory being right. So
- * use cvs-servPID.
- */
- strcat (server_temp_dir, "/cvs-serv");
+ /*
+ * I wanted to use cvs-serv/PID, but then you have to worry about
+ * the permissions on the cvs-serv directory being right. So
+ * use cvs-servPID.
+ */
+ strcat (server_temp_dir, "/cvs-serv");
+
+ p = server_temp_dir + strlen (server_temp_dir);
+ sprintf (p, "%ld", (long) getpid ());
- p = server_temp_dir + strlen (server_temp_dir);
- sprintf (p, "%ld", (long) getpid ());
+ orig_server_temp_dir = server_temp_dir;
+ }
}
(void) SIG_register (SIGHUP, server_cleanup);
@@ -4197,13 +3773,15 @@ error ENOMEM Virtual memory exhausted.\n");
}
argument_count = 1;
- argument_vector[0] = "Dummy argument 0";
-
- buf_to_net.data = buf_to_net.last = NULL;
- buf_to_net.fd = STDOUT_FILENO;
- buf_to_net.output = 1;
- buf_to_net.nonblocking = 0;
- buf_to_net.memory_error = outbuf_memory_error;
+ /* This gets printed if the client supports an option which the
+ server doesn't, causing the server to print a usage message.
+ FIXME: probably should be using program_name here.
+ FIXME: just a nit, I suppose, but the usage message the server
+ prints isn't literally true--it suggests "cvs server" followed
+ by options which are for a particular command. Might be nice to
+ say something like "client apparently supports an option not supported
+ by this server" or something like that instead of usage message. */
+ argument_vector[0] = "cvs server";
server_active = 1;
@@ -4211,16 +3789,19 @@ error ENOMEM Virtual memory exhausted.\n");
{
char *cmd, *orig_cmd;
struct request *rq;
+ int status;
- orig_cmd = cmd = read_line (stdin);
- if (cmd == NULL)
- break;
- if (cmd == NO_MEM_ERROR)
+ status = buf_read_line (buf_from_net, &cmd, (int *) NULL);
+ if (status == -2)
{
- printf ("E Fatal server error, aborting.\n\
+ buf_output0 (buf_to_net, "E Fatal server error, aborting.\n\
error ENOMEM Virtual memory exhausted.\n");
break;
}
+ if (status != 0)
+ break;
+
+ orig_cmd = cmd;
for (rq = requests; rq->name != NULL; ++rq)
if (strncmp (cmd, rq->name, strlen (rq->name)) == 0)
{
@@ -4242,7 +3823,12 @@ error ENOMEM Virtual memory exhausted.\n");
if (rq->name == NULL)
{
if (!print_pending_error ())
- printf ("error unrecognized request `%s'\n", cmd);
+ {
+ buf_output0 (buf_to_net, "error unrecognized request `");
+ buf_output0 (buf_to_net, cmd);
+ buf_append_char (buf_to_net, '\'');
+ buf_append_char (buf_to_net, '\n');
+ }
}
free (orig_cmd);
}
@@ -4251,22 +3837,66 @@ error ENOMEM Virtual memory exhausted.\n");
}
-#ifdef AUTH_SERVER_SUPPORT
+#if defined (HAVE_KERBEROS) || defined (AUTH_SERVER_SUPPORT)
+static void switch_to_user PROTO((const char *));
-extern char *crypt PROTO((const char *, const char *));
+static void
+switch_to_user (username)
+ const char *username;
+{
+ struct passwd *pw;
+
+ pw = getpwnam (username);
+ if (pw == NULL)
+ {
+ printf ("E Fatal error, aborting.\n\
+error 0 %s: no such user\n", username);
+ exit (EXIT_FAILURE);
+ }
+
+#if HAVE_INITGROUPS
+ initgroups (pw->pw_name, pw->pw_gid);
+#endif /* HAVE_INITGROUPS */
-/* This was test code, which we may need again. */
-#if 0
- /* If we were invoked this way, then stdin comes from the
- client and stdout/stderr writes to it. */
- int c;
- while ((c = getc (stdin)) != EOF && c != '*')
+#ifdef SETXID_SUPPORT
+ /* honor the setgid bit iff set*/
+ if (getgid() != getegid())
+ {
+ setgid (getegid ());
+ }
+ else
+#else
{
- printf ("%c", toupper (c));
- fflush (stdout);
+ setgid (pw->pw_gid);
}
- exit (0);
-#endif /* 1/0 */
+#endif
+
+ setuid (pw->pw_uid);
+ /* Inhibit access by randoms. Don't want people randomly
+ changing our temporary tree before we check things in. */
+ umask (077);
+
+#if HAVE_PUTENV
+ /* Set LOGNAME and USER in the environment, in case they are
+ already set to something else. */
+ {
+ char *env;
+
+ env = xmalloc (sizeof "LOGNAME=" + strlen (username));
+ (void) sprintf (env, "LOGNAME=%s", username);
+ (void) putenv (env);
+
+ env = xmalloc (sizeof "USER=" + strlen (username));
+ (void) sprintf (env, "USER=%s", username);
+ (void) putenv (env);
+ }
+#endif /* HAVE_PUTENV */
+}
+#endif
+
+#ifdef AUTH_SERVER_SUPPORT
+
+extern char *crypt PROTO((const char *, const char *));
/*
@@ -4274,14 +3904,15 @@ extern char *crypt PROTO((const char *, const char *));
* 1 means entry found and password matches.
* 2 means entry found, but password does not match.
*/
-int
+static int
check_repository_password (username, password, repository, host_user_ptr)
char *username, *password, *repository, **host_user_ptr;
{
int retval = 0;
FILE *fp;
char *filename;
- char *linebuf;
+ char *linebuf = NULL;
+ size_t linebuf_len;
int found_it = 0;
int namelen;
@@ -4295,8 +3926,8 @@ check_repository_password (username, password, repository, host_user_ptr)
strcpy (filename, repository);
strcat (filename, "/CVSROOT");
strcat (filename, "/passwd");
-
- fp = fopen (filename, "r");
+
+ fp = CVS_FOPEN (filename, "r");
if (fp == NULL)
{
if (!existence_error (errno))
@@ -4306,19 +3937,8 @@ check_repository_password (username, password, repository, host_user_ptr)
/* Look for a relevant line -- one with this user's name. */
namelen = strlen (username);
- while (1)
+ while (getline (&linebuf, &linebuf_len, fp) >= 0)
{
- linebuf = read_line(fp);
- if (linebuf == NULL)
- {
- free (linebuf);
- break;
- }
- if (linebuf == NO_MEM_ERROR)
- {
- error (0, errno, "out of memory");
- break;
- }
if ((strncmp (linebuf, username, namelen) == 0)
&& (linebuf[namelen] == ':'))
{
@@ -4326,7 +3946,7 @@ check_repository_password (username, password, repository, host_user_ptr)
break;
}
free (linebuf);
-
+ linebuf = NULL;
}
if (ferror (fp))
error (0, errno, "cannot read %s", filename);
@@ -4360,7 +3980,7 @@ check_repository_password (username, password, repository, host_user_ptr)
/* Return a hosting username if password matches, else NULL. */
-char *
+static char *
check_password (username, password, repository)
char *username, *password, *repository;
{
@@ -4382,18 +4002,32 @@ check_password (username, password, repository)
{
/* No cvs password found, so try /etc/passwd. */
+ const char *found_passwd = NULL;
+#ifdef HAVE_GETSPNAM
+ struct spwd *pw;
+
+ pw = getspnam (username);
+ if (pw != NULL)
+ {
+ found_passwd = pw->sp_pwdp;
+ }
+#else
struct passwd *pw;
- char *found_passwd;
pw = getpwnam (username);
+ if (pw != NULL)
+ {
+ found_passwd = pw->pw_passwd;
+ }
+#endif
+
if (pw == NULL)
- {
+ {
printf ("E Fatal error, aborting.\n\
error 0 %s: no such user\n", username);
exit (EXIT_FAILURE);
}
- found_passwd = pw->pw_passwd;
-
+
if (found_passwd && *found_passwd)
return ((! strcmp (found_passwd, crypt (password, found_passwd)))
? username : NULL);
@@ -4410,193 +4044,617 @@ error 0 %s: no such user\n", username);
}
}
-
/* Read username and password from client (i.e., stdin).
If correct, then switch to run as that user and send an ACK to the
client via stdout, else send NACK and die. */
void
-authenticate_connection ()
+pserver_authenticate_connection ()
{
- char tmp[PATH_MAX];
- char repository[PATH_MAX];
- char username[PATH_MAX];
- char password[PATH_MAX];
- char *host_user;
- char *descrambled_password;
- struct passwd *pw;
- int verify_and_exit = 0;
-
- /* The Authentication Protocol. Client sends:
- *
- * BEGIN AUTH REQUEST\n
- * <REPOSITORY>\n
- * <USERNAME>\n
- * <PASSWORD>\n
- * END AUTH REQUEST\n
- *
- * Server uses above information to authenticate, then sends
- *
- * I LOVE YOU\n
- *
- * if it grants access, else
- *
- * I HATE YOU\n
- *
- * if it denies access (and it exits if denying).
- *
- * When the client is "cvs login", the user does not desire actual
- * repository access, but would like to confirm the password with
- * the server. In this case, the start and stop strings are
- *
- * BEGIN VERIFICATION REQUEST\n
- *
- * and
- *
- * END VERIFICATION REQUEST\n
- *
- * On a verification request, the server's responses are the same
- * (with the obvious semantics), but it exits immediately after
- * sending the response in both cases.
- *
- * Why is the repository sent? Well, note that the actual
- * client/server protocol can't start up until authentication is
- * successful. But in order to perform authentication, the server
- * needs to look up the password in the special CVS passwd file,
- * before trying /etc/passwd. So the client transmits the
- * repository as part of the "authentication protocol". The
- * repository will be redundantly retransmitted later, but that's no
- * big deal.
- */
-
- /* Since we're in the server parent process, error should use the
- protocol to report error messages. */
- error_use_protocol = 1;
-
- /* Make sure the protocol starts off on the right foot... */
- fgets (tmp, PATH_MAX, stdin);
- if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
- verify_and_exit = 1;
- else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") != 0)
- error (1, 0, "bad auth protocol start: %s", tmp);
-
- /* Get the three important pieces of information in order. */
- fgets (repository, PATH_MAX, stdin);
- fgets (username, PATH_MAX, stdin);
- fgets (password, PATH_MAX, stdin);
-
- /* Make them pure. */
- strip_trailing_newlines (repository);
- strip_trailing_newlines (username);
- strip_trailing_newlines (password);
-
- /* ... and make sure the protocol ends on the right foot. */
- fgets (tmp, PATH_MAX, stdin);
- if (strcmp (tmp,
- verify_and_exit ?
- "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n")
- != 0)
- {
- error (1, 0, "bad auth protocol end: %s", tmp);
- }
-
- /* We need the real cleartext before we hash it. */
- descrambled_password = descramble (password);
- host_user = check_password (username, descrambled_password, repository);
- if (host_user)
- {
- printf ("I LOVE YOU\n");
- fflush (stdout);
- memset (descrambled_password, 0, strlen (descrambled_password));
- free (descrambled_password);
- }
- else
- {
- printf ("I HATE YOU\n");
- fflush (stdout);
- memset (descrambled_password, 0, strlen (descrambled_password));
- free (descrambled_password);
- exit (EXIT_FAILURE);
- }
-
- /* Don't go any farther if we're just responding to "cvs login". */
- if (verify_and_exit)
- exit (0);
-
- /* Switch to run as this user. */
- pw = getpwnam (host_user);
- if (pw == NULL)
- {
- error (1, 0,
- "fatal error, aborting.\nerror 0 %s: no such user\n",
- username);
- }
-
-#if HAVE_INITGROUPS
- initgroups (pw->pw_name, pw->pw_gid);
-#endif /* HAVE_INITGROUPS */
+ char tmp[PATH_MAX];
+ char repository[PATH_MAX];
+ char username[PATH_MAX];
+ char password[PATH_MAX];
+ char *host_user;
+ char *descrambled_password;
+ int verify_and_exit = 0;
+
+ /* The Authentication Protocol. Client sends:
+ *
+ * BEGIN AUTH REQUEST\n
+ * <REPOSITORY>\n
+ * <USERNAME>\n
+ * <PASSWORD>\n
+ * END AUTH REQUEST\n
+ *
+ * Server uses above information to authenticate, then sends
+ *
+ * I LOVE YOU\n
+ *
+ * if it grants access, else
+ *
+ * I HATE YOU\n
+ *
+ * if it denies access (and it exits if denying).
+ *
+ * When the client is "cvs login", the user does not desire actual
+ * repository access, but would like to confirm the password with
+ * the server. In this case, the start and stop strings are
+ *
+ * BEGIN VERIFICATION REQUEST\n
+ *
+ * and
+ *
+ * END VERIFICATION REQUEST\n
+ *
+ * On a verification request, the server's responses are the same
+ * (with the obvious semantics), but it exits immediately after
+ * sending the response in both cases.
+ *
+ * Why is the repository sent? Well, note that the actual
+ * client/server protocol can't start up until authentication is
+ * successful. But in order to perform authentication, the server
+ * needs to look up the password in the special CVS passwd file,
+ * before trying /etc/passwd. So the client transmits the
+ * repository as part of the "authentication protocol". The
+ * repository will be redundantly retransmitted later, but that's no
+ * big deal.
+ */
- setgid (pw->pw_gid);
- setuid (pw->pw_uid);
- /* Inhibit access by randoms. Don't want people randomly
- changing our temporary tree before we check things in. */
- umask (077);
-
-#if HAVE_PUTENV
- /* Set LOGNAME and USER in the environment, in case they are
- already set to something else. */
- {
- char *env;
-
- env = xmalloc (sizeof "LOGNAME=" + strlen (username));
- (void) sprintf (env, "LOGNAME=%s", username);
- (void) putenv (env);
-
- env = xmalloc (sizeof "USER=" + strlen (username));
- (void) sprintf (env, "USER=%s", username);
- (void) putenv (env);
- }
-#endif /* HAVE_PUTENV */
+#ifdef SO_KEEPALIVE
+ /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
+ if the client dies while we are waiting for input. */
+ {
+ int on = 1;
+
+ (void) setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
+ (char *) &on, sizeof on);
+ }
+#endif
+
+ /* Make sure the protocol starts off on the right foot... */
+ fgets (tmp, PATH_MAX, stdin);
+ if (strcmp (tmp, "BEGIN VERIFICATION REQUEST\n") == 0)
+ verify_and_exit = 1;
+ else if (strcmp (tmp, "BEGIN AUTH REQUEST\n") != 0)
+ error (1, 0, "bad auth protocol start: %s", tmp);
+
+ /* Get the three important pieces of information in order. */
+ fgets (repository, PATH_MAX, stdin);
+ fgets (username, PATH_MAX, stdin);
+ fgets (password, PATH_MAX, stdin);
+
+ /* Make them pure. */
+ strip_trailing_newlines (repository);
+ strip_trailing_newlines (username);
+ strip_trailing_newlines (password);
+
+ /* ... and make sure the protocol ends on the right foot. */
+ fgets (tmp, PATH_MAX, stdin);
+ if (strcmp (tmp,
+ verify_and_exit ?
+ "END VERIFICATION REQUEST\n" : "END AUTH REQUEST\n")
+ != 0)
+ {
+ error (1, 0, "bad auth protocol end: %s", tmp);
+ }
+
+ /* We need the real cleartext before we hash it. */
+ descrambled_password = descramble (password);
+ host_user = check_password (username, descrambled_password, repository);
+ memset (descrambled_password, 0, strlen (descrambled_password));
+ free (descrambled_password);
+ if (host_user)
+ {
+ printf ("I LOVE YOU\n");
+ fflush (stdout);
+ }
+ else
+ {
+ printf ("I HATE YOU\n");
+ fflush (stdout);
+ exit (EXIT_FAILURE);
+ }
+
+ /* Don't go any farther if we're just responding to "cvs login". */
+ if (verify_and_exit)
+ exit (0);
+
+ /* Switch to run as this user. */
+ switch_to_user (host_user);
}
#endif /* AUTH_SERVER_SUPPORT */
+#ifdef HAVE_KERBEROS
+void
+kserver_authenticate_connection ()
+{
+ int status;
+ char instance[INST_SZ];
+ struct sockaddr_in peer;
+ struct sockaddr_in laddr;
+ int len;
+ KTEXT_ST ticket;
+ AUTH_DAT auth;
+ char version[KRB_SENDAUTH_VLEN];
+ char user[ANAME_SZ];
+
+ strcpy (instance, "*");
+ len = sizeof peer;
+ if (getpeername (STDIN_FILENO, (struct sockaddr *) &peer, &len) < 0
+ || getsockname (STDIN_FILENO, (struct sockaddr *) &laddr,
+ &len) < 0)
+ {
+ printf ("E Fatal error, aborting.\n\
+error %s getpeername or getsockname failed\n", strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+
+#ifdef SO_KEEPALIVE
+ /* Set SO_KEEPALIVE on the socket, so that we don't hang forever
+ if the client dies while we are waiting for input. */
+ {
+ int on = 1;
+
+ (void) setsockopt (STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE,
+ (char *) &on, sizeof on);
+ }
+#endif
+
+ status = krb_recvauth (KOPT_DO_MUTUAL, STDIN_FILENO, &ticket, "rcmd",
+ instance, &peer, &laddr, &auth, "", sched,
+ version);
+ if (status != KSUCCESS)
+ {
+ printf ("E Fatal error, aborting.\n\
+error 0 kerberos: %s\n", krb_get_err_text(status));
+ exit (EXIT_FAILURE);
+ }
+
+ memcpy (kblock, auth.session, sizeof (C_Block));
+
+ /* Get the local name. */
+ status = krb_kntoln (&auth, user);
+ if (status != KSUCCESS)
+ {
+ printf ("E Fatal error, aborting.\n\
+error 0 kerberos: can't get local name: %s\n", krb_get_err_text(status));
+ exit (EXIT_FAILURE);
+ }
+
+ /* Switch to run as this user. */
+ switch_to_user (user);
+}
+#endif /* HAVE_KERBEROS */
+
#endif /* SERVER_SUPPORT */
+#if defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT)
+
+/* This global variable is non-zero if the user requests encryption on
+ the command line. */
+int cvsencrypt;
+
+#ifdef ENCRYPTION
+
+#ifdef HAVE_KERBEROS
+
+/* An encryption interface using Kerberos. This is built on top of
+ the buffer structure. We encrypt using a big endian two byte count
+ field followed by a block of encrypted data. */
+
+/* This structure is the closure field of a Kerberos encryption
+ buffer. */
+
+struct krb_encrypt_buffer
+{
+ /* The underlying buffer. */
+ struct buffer *buf;
+ /* The Kerberos key schedule. */
+ Key_schedule sched;
+ /* The Kerberos DES block. */
+ C_Block block;
+ /* For an input buffer, we may have to buffer up data here. */
+ /* This is non-zero if the buffered data is decrypted. Otherwise,
+ the buffered data is encrypted, and starts with the two byte
+ count. */
+ int clear;
+ /* The amount of buffered data. */
+ int holdsize;
+ /* The buffer allocated to hold the data. */
+ char *holdbuf;
+ /* The size of holdbuf. */
+ int holdbufsize;
+ /* If clear is set, we need another data pointer to track where we
+ are in holdbuf. If clear is zero, then this pointer is not
+ used. */
+ char *holddata;
+};
+
+static int krb_encrypt_buffer_input PROTO((void *, char *, int, int, int *));
+static int krb_encrypt_buffer_output PROTO((void *, const char *, int, int *));
+static int krb_encrypt_buffer_flush PROTO((void *));
+static int krb_encrypt_buffer_block PROTO((void *, int));
+static int krb_encrypt_buffer_shutdown PROTO((void *));
+
+/* Create an encryption buffer. */
+
+struct buffer *
+krb_encrypt_buffer_initialize (buf, input, sched, block, memory)
+ struct buffer *buf;
+ int input;
+ Key_schedule sched;
+ C_Block block;
+ void (*memory) PROTO((struct buffer *));
+{
+ struct krb_encrypt_buffer *kb;
+
+ kb = (struct krb_encrypt_buffer *) xmalloc (sizeof *kb);
+ memset (kb, 0, sizeof *kb);
+
+ kb->buf = buf;
+ memcpy (kb->sched, sched, sizeof (Key_schedule));
+ memcpy (kb->block, block, sizeof (C_Block));
+ if (input)
+ {
+ /* We add some space to the buffer to hold the length. */
+ kb->holdbufsize = BUFFER_DATA_SIZE + 16;
+ kb->holdbuf = xmalloc (kb->holdbufsize);
+ }
+
+ return buf_initialize (input ? krb_encrypt_buffer_input : NULL,
+ input ? NULL : krb_encrypt_buffer_output,
+ input ? NULL : krb_encrypt_buffer_flush,
+ krb_encrypt_buffer_block,
+ krb_encrypt_buffer_shutdown,
+ memory,
+ kb);
+}
+
+/* Input data from a Kerberos encryption buffer. */
+
+static int
+krb_encrypt_buffer_input (closure, data, need, size, got)
+ void *closure;
+ char *data;
+ int need;
+ int size;
+ int *got;
+{
+ struct krb_encrypt_buffer *kb = (struct krb_encrypt_buffer *) closure;
+
+ *got = 0;
+
+ if (kb->holdsize > 0 && kb->clear)
+ {
+ int copy;
+
+ copy = kb->holdsize;
+
+ if (copy > size)
+ {
+ memcpy (data, kb->holddata, size);
+ kb->holdsize -= size;
+ kb->holddata += size;
+ *got = size;
+ return 0;
+ }
+
+ memcpy (data, kb->holddata, copy);
+ kb->holdsize = 0;
+ kb->clear = 0;
+
+ data += copy;
+ need -= copy;
+ size -= copy;
+ *got = copy;
+ }
+
+ while (need > 0 || *got == 0)
+ {
+ int get, status, nread, count, dcount;
+ char *bytes;
+ char stackoutbuf[BUFFER_DATA_SIZE + 16];
+ char *outbuf;
+
+ /* If we don't already have the two byte count, get it. */
+ if (kb->holdsize < 2)
+ {
+ get = 2 - kb->holdsize;
+ status = buf_read_data (kb->buf, get, &bytes, &nread);
+ if (status != 0)
+ {
+ /* buf_read_data can return -2, but a buffer input
+ function is only supposed to return -1, 0, or an
+ error code. */
+ if (status == -2)
+ status = ENOMEM;
+ return status;
+ }
+
+ if (nread == 0)
+ {
+ /* The buffer is in nonblocking mode, and we didn't
+ manage to read anything. */
+ return 0;
+ }
+
+ if (get == 1)
+ kb->holdbuf[1] = bytes[0];
+ else
+ {
+ kb->holdbuf[0] = bytes[0];
+ if (nread < 2)
+ {
+ /* We only got one byte, but we needed two. Stash
+ the byte we got, and try again. */
+ kb->holdsize = 1;
+ continue;
+ }
+ kb->holdbuf[1] = bytes[1];
+ }
+ kb->holdsize = 2;
+ }
+
+ /* Read the encrypted block of data. */
+
+ count = (((kb->holdbuf[0] & 0xff) << 8)
+ + (kb->holdbuf[1] & 0xff));
+
+ if (count + 2 > kb->holdbufsize)
+ {
+ char *n;
+
+ /* This should be impossible, since we should have
+ allocated space for the largest possible block in the
+ initialize function. However, we handle it just in
+ case something changes in the future, so that a current
+ server can handle a later client. */
+
+ n = realloc (kb->holdbuf, count + 2);
+ if (n == NULL)
+ {
+ (*kb->buf->memory_error) (kb->buf);
+ return ENOMEM;
+ }
+ kb->holdbuf = n;
+ kb->holdbufsize = count + 2;
+ }
+
+ get = count - (kb->holdsize - 2);
+
+ status = buf_read_data (kb->buf, get, &bytes, &nread);
+ if (status != 0)
+ {
+ /* buf_read_data can return -2, but a buffer input
+ function is only supposed to return -1, 0, or an error
+ code. */
+ if (status == -2)
+ status = ENOMEM;
+ return status;
+ }
+
+ if (nread == 0)
+ {
+ /* We did not get any data. Presumably the buffer is in
+ nonblocking mode. */
+ return 0;
+ }
+
+ /* FIXME: We could complicate the code here to avoid this
+ memcpy in the common case of kb->holdsize == 2 && nread ==
+ get. */
+ memcpy (kb->holdbuf + kb->holdsize, bytes, nread);
+ kb->holdsize += nread;
+
+ if (nread < get)
+ {
+ /* We did not get all the data we need. buf_read_data
+ does not promise to return all the bytes requested, so
+ we must try again. */
+ continue;
+ }
+
+ /* We have a complete encrypted block of COUNT bytes at
+ KB->HOLDBUF + 2. Decrypt it. */
+
+ if (count <= sizeof stackoutbuf)
+ outbuf = stackoutbuf;
+ else
+ {
+ /* I believe this is currently impossible, but we handle
+ it for the benefit of future client changes. */
+ outbuf = malloc (count);
+ if (outbuf == NULL)
+ {
+ (*kb->buf->memory_error) (kb->buf);
+ return ENOMEM;
+ }
+ }
+
+ des_cbc_encrypt ((C_Block *) (kb->holdbuf + 2), (C_Block *) outbuf,
+ count, kb->sched, &kb->block, 0);
+
+ /* The first two bytes in the decrypted buffer are the real
+ (unaligned) length. */
+ dcount = ((outbuf[0] & 0xff) << 8) + (outbuf[1] & 0xff);
+
+ if (((dcount + 2 + 7) & ~7) != count)
+ error (1, 0, "Decryption failure");
+
+ if (dcount > size)
+ {
+ /* We have too much data for the buffer. We need to save
+ some of it for the next call. */
+
+ memcpy (data, outbuf + 2, size);
+ *got += size;
+
+ kb->holdsize = dcount - size;
+ memcpy (kb->holdbuf, outbuf + 2 + size, dcount - size);
+ kb->holddata = kb->holdbuf;
+ kb->clear = 1;
+
+ if (outbuf != stackoutbuf)
+ free (outbuf);
+
+ return 0;
+ }
+
+ memcpy (data, outbuf + 2, dcount);
+
+ if (outbuf != stackoutbuf)
+ free (outbuf);
+
+ kb->holdsize = 0;
+
+ data += dcount;
+ need -= dcount;
+ size -= dcount;
+ *got += dcount;
+ }
+
+ return 0;
+}
+
+/* Output data to a Kerberos encryption buffer. */
+
+static int
+krb_encrypt_buffer_output (closure, data, have, wrote)
+ void *closure;
+ const char *data;
+ int have;
+ int *wrote;
+{
+ struct krb_encrypt_buffer *kb = (struct krb_encrypt_buffer *) closure;
+ char inbuf[BUFFER_DATA_SIZE + 16];
+ char outbuf[BUFFER_DATA_SIZE + 16];
+ int aligned;
+
+ if (have > BUFFER_DATA_SIZE)
+ {
+ /* It would be easy to malloc a buffer, but I don't think this
+ case can ever arise. */
+ abort ();
+ }
+
+ inbuf[0] = (have >> 8) & 0xff;
+ inbuf[1] = have & 0xff;
+ memcpy (inbuf + 2, data, have);
+
+ /* For security against a known plaintext attack, we should
+ initialize any padding bytes to random values. Instead, we
+ just pick up whatever is on the stack, which is at least better
+ than using zero. */
+
+ /* Align (have + 2) (plus 2 for the count) to an 8 byte boundary. */
+ aligned = (have + 2 + 7) & ~7;
+
+ /* We use des_cbc_encrypt rather than krb_mk_priv because the
+ latter sticks a timestamp in the block, and krb_rd_priv expects
+ that timestamp to be within five minutes of the current time.
+ Given the way the CVS server buffers up data, that can easily
+ fail over a long network connection. We trust krb_recvauth to
+ guard against a replay attack. */
+
+ des_cbc_encrypt ((C_Block *) inbuf, (C_Block *) (outbuf + 2), aligned,
+ kb->sched, &kb->block, 1);
+
+ outbuf[0] = (aligned >> 8) & 0xff;
+ outbuf[1] = aligned & 0xff;
+
+ /* FIXME: It would be more efficient to get des_cbc_encrypt to put
+ its output directly into a buffer_data structure, which we
+ could then append to kb->buf. That would save a memcpy. */
+
+ buf_output (kb->buf, outbuf, aligned + 2);
+
+ *wrote = have;
+
+ /* We will only be here because buf_send_output was called on the
+ encryption buffer. That means that we should now call
+ buf_send_output on the underlying buffer. */
+ return buf_send_output (kb->buf);
+}
+
+/* Flush data to a Kerberos encryption buffer. */
+
+static int
+krb_encrypt_buffer_flush (closure)
+ void *closure;
+{
+ struct krb_encrypt_buffer *kb = (struct krb_encrypt_buffer *) closure;
+
+ /* Flush the underlying buffer. Note that if the original call to
+ buf_flush passed 1 for the BLOCK argument, then the buffer will
+ already have been set into blocking mode, so we should always
+ pass 0 here. */
+ return buf_flush (kb->buf, 0);
+}
+
+/* The block routine for a Kerberos encryption buffer. */
+
+static int
+krb_encrypt_buffer_block (closure, block)
+ void *closure;
+ int block;
+{
+ struct krb_encrypt_buffer *kb = (struct krb_encrypt_buffer *) closure;
+
+ if (block)
+ return set_block (kb->buf);
+ else
+ return set_nonblock (kb->buf);
+}
+
+/* Shut down a Kerberos encryption buffer. */
+
+static int
+krb_encrypt_buffer_shutdown (closure)
+ void *closure;
+{
+ struct krb_encrypt_buffer *kb = (struct krb_encrypt_buffer *) closure;
+
+ return buf_shutdown (kb->buf);
+}
+
+#endif /* HAVE_KERBEROS */
+#endif /* ENCRYPTION */
+#endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */
+
/* Output LEN bytes at STR. If LEN is zero, then output up to (not including)
- the first '\0' byte. Should not be called from the server parent process
- (yet at least, in the future it might be extended so that works). */
+ the first '\0' byte. */
void
cvs_output (str, len)
- char *str;
+ const char *str;
size_t len;
{
if (len == 0)
len = strlen (str);
- if (error_use_protocol)
- /* Eventually we'll probably want to make it so this case works,
- but for now, callers who want to output something with
- error_use_protocol in effect can just printf the "M foo"
- themselves. */
- abort ();
#ifdef SERVER_SUPPORT
- if (server_active)
+ if (error_use_protocol)
+ {
+ buf_output (saved_output, str, len);
+ buf_copy_lines (buf_to_net, saved_output, 'M');
+ }
+ else if (server_active)
{
- buf_output (&saved_output, str, len);
- buf_copy_lines (&protocol, &saved_output, 'M');
- buf_send_counted (&protocol);
+ buf_output (saved_output, str, len);
+ buf_copy_lines (protocol, saved_output, 'M');
+ buf_send_counted (protocol);
}
else
#endif
{
size_t written;
size_t to_write = len;
- char *p = str;
+ const char *p = str;
while (to_write > 0)
{
- written = fwrite (str, 1, to_write, stdout);
+ written = fwrite (p, 1, to_write, stdout);
if (written == 0)
break;
p += written;
@@ -4609,34 +4667,33 @@ cvs_output (str, len)
void
cvs_outerr (str, len)
- char *str;
+ const char *str;
size_t len;
{
if (len == 0)
len = strlen (str);
- if (error_use_protocol)
- /* Eventually we'll probably want to make it so this case works,
- but for now, callers who want to output something with
- error_use_protocol in effect can just printf the "E foo"
- themselves. */
- abort ();
#ifdef SERVER_SUPPORT
- if (server_active)
+ if (error_use_protocol)
{
- buf_output (&saved_outerr, str, len);
- buf_copy_lines (&protocol, &saved_outerr, 'E');
- buf_send_counted (&protocol);
+ buf_output (saved_outerr, str, len);
+ buf_copy_lines (buf_to_net, saved_outerr, 'E');
+ }
+ else if (server_active)
+ {
+ buf_output (saved_outerr, str, len);
+ buf_copy_lines (protocol, saved_outerr, 'E');
+ buf_send_counted (protocol);
}
else
#endif
{
size_t written;
size_t to_write = len;
- char *p = str;
+ const char *p = str;
while (to_write > 0)
{
- written = fwrite (str, 1, to_write, stderr);
+ written = fwrite (p, 1, to_write, stderr);
if (written == 0)
break;
p += written;
@@ -4644,3 +4701,26 @@ cvs_outerr (str, len)
}
}
}
+
+/* Flush stderr. stderr is normally flushed automatically, of course,
+ but this function is used to flush information from the server back
+ to the client. */
+
+void
+cvs_flusherr ()
+{
+#ifdef SERVER_SUPPORT
+ if (error_use_protocol)
+ {
+ /* Flush what we can to the network, but don't block. */
+ buf_flush (buf_to_net, 0);
+ }
+ else if (server_active)
+ {
+ /* Send a special count to tell the parent to flush. */
+ buf_send_special_count (protocol, -1);
+ }
+ else
+#endif
+ fflush (stderr);
+}
diff --git a/gnu/usr.bin/cvs/src/update.c b/gnu/usr.bin/cvs/src/update.c
index eddfe5a9971..c1a8d11846f 100644
--- a/gnu/usr.bin/cvs/src/update.c
+++ b/gnu/usr.bin/cvs/src/update.c
@@ -41,31 +41,32 @@
#include "fileattr.h"
#include "edit.h"
-static int checkout_file PROTO((char *file, char *repository, List *entries,
- RCSNode *rcsnode, Vers_TS *vers_ts, char *update_dir));
+static int checkout_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts,
+ int adding));
#ifdef SERVER_SUPPORT
-static int patch_file PROTO((char *file, char *repository, List *entries,
- RCSNode*rcsnode, Vers_TS *vers_ts, char *update_dir,
- int *docheckout, struct stat *file_info,
- unsigned char *checksum));
+static int patch_file PROTO ((struct file_info *finfo,
+ Vers_TS *vers_ts,
+ int *docheckout, struct stat *file_info,
+ unsigned char *checksum));
#endif
static int isemptydir PROTO((char *dir));
-static int merge_file PROTO((char *file, char *repository, List *entries,
- Vers_TS *vers, char *update_dir));
-static int scratch_file PROTO((char *file, char *repository, List * entries,
- char *update_dir));
-static Dtype update_dirent_proc PROTO((char *dir, char *repository, char *update_dir));
-static int update_dirleave_proc PROTO((char *dir, int err, char *update_dir));
-static int update_fileproc PROTO ((struct file_info *));
-static int update_filesdone_proc PROTO((int err, char *repository,
- char *update_dir));
+static int merge_file PROTO ((struct file_info *finfo, Vers_TS *vers));
+static int scratch_file PROTO((struct file_info *finfo));
+static Dtype update_dirent_proc PROTO ((void *callerdat, char *dir,
+ char *repository, char *update_dir,
+ List *entries));
+static int update_dirleave_proc PROTO ((void *callerdat, char *dir,
+ int err, char *update_dir,
+ List *entries));
+static int update_fileproc PROTO ((void *callerdat, struct file_info *));
+static int update_filesdone_proc PROTO ((void *callerdat, int err,
+ char *repository, char *update_dir,
+ List *entries));
static int write_letter PROTO((char *file, int letter, char *update_dir));
#ifdef SERVER_SUPPORT
-static void join_file PROTO((char *file, RCSNode *rcsnode, Vers_TS *vers_ts,
- char *update_dir, List *entries, char *repository));
+static void join_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts));
#else
-static void join_file PROTO((char *file, RCSNode *rcsnode, Vers_TS *vers_ts,
- char *update_dir, List *entries));
+static void join_file PROTO ((struct file_info *finfo, Vers_TS *vers_ts));
#endif
static char *options = NULL;
@@ -93,10 +94,10 @@ static const char *const update_usage[] =
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, no recursion.\n",
"\t-R\tProcess directories recursively.\n",
- "\t-p\tSend updates to standard output.\n",
+ "\t-p\tSend updates to standard output (avoids stickiness).\n",
"\t-k kopt\tUse RCS kopt -k option on checkout.\n",
- "\t-r rev\tUpdate using specified revision/tag.\n",
- "\t-D date\tSet date to update from.\n",
+ "\t-r rev\tUpdate using specified revision/tag (is sticky).\n",
+ "\t-D date\tSet date to update from (is sticky).\n",
"\t-j rev\tMerge in changes made between current revision and rev.\n",
"\t-I ign\tMore files to ignore (! to reset).\n",
"\t-W spec\tWrappers specification line.\n",
@@ -228,31 +229,28 @@ update (argc, argv)
send_arg("-P");
client_prune_dirs = update_prune_dirs;
option_with_arg ("-r", tag);
+ if (options && options[0] != '\0')
+ send_arg (options);
if (date)
client_senddate (date);
if (join_rev1)
option_with_arg ("-j", join_rev1);
if (join_rev2)
option_with_arg ("-j", join_rev2);
+ wrap_send ();
/* If the server supports the command "update-patches", that means
that it knows how to handle the -u argument to update, which
means to send patches instead of complete files. */
if (failed_patches == NULL)
{
- struct request *rq;
-
- for (rq = requests; rq->name != NULL; rq++)
- {
- if (strcmp (rq->name, "update-patches") == 0)
- {
- if (rq->status == rq_supported)
- {
- send_arg("-u");
- }
- break;
- }
- }
+#ifndef DONT_USE_PATCH
+ /* Systems which don't have the patch program ported to them
+ will want to define DONT_USE_PATCH; then CVS won't try to
+ invoke patch. */
+ if (supported_request ("update-patches"))
+ send_arg ("-u");
+#endif
}
if (failed_patches == NULL)
@@ -268,7 +266,7 @@ update (argc, argv)
program_name);
if (toplevel_wd[0] != '\0'
- && chdir (toplevel_wd) < 0)
+ && CVS_CHDIR (toplevel_wd) < 0)
{
error (1, errno, "could not chdir to %s", toplevel_wd);
}
@@ -297,8 +295,10 @@ update (argc, argv)
if (tag != NULL)
tag_check_valid (tag, argc, argv, local, aflag, "");
- /* FIXME: We don't call tag_check_valid on join_rev1 and join_rev2
- yet (make sure to handle ':' correctly if we do, though). */
+ if (join_rev1 != NULL)
+ tag_check_valid_join (join_rev1, argc, argv, local, aflag, "");
+ if (join_rev2 != NULL)
+ tag_check_valid_join (join_rev2, argc, argv, local, aflag, "");
/*
* If we are updating the entire directory (for real) and building dirs
@@ -402,9 +402,9 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
/* call the recursion processor */
err = start_recursion (update_fileproc, update_filesdone_proc,
- update_dirent_proc, update_dirleave_proc,
+ update_dirent_proc, update_dirleave_proc, NULL,
argc, argv, local, which, aflag, 1,
- preload_update_dir, 1, 0);
+ preload_update_dir, 1);
/* see if we need to sleep before returning */
if (last_register_time)
@@ -431,16 +431,19 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
* appropriate magic for checkout
*/
static int
-update_fileproc (finfo)
+update_fileproc (callerdat, finfo)
+ void *callerdat;
struct file_info *finfo;
{
int retval;
Ctype status;
Vers_TS *vers;
+ int resurrecting;
+
+ resurrecting = 0;
- status = Classify_File (finfo->file, tag, date, options, force_tag_match,
- aflag, finfo->repository, finfo->entries, finfo->rcs, &vers,
- finfo->update_dir, pipeout);
+ status = Classify_File (finfo, tag, date, options, force_tag_match,
+ aflag, &vers, pipeout);
if (pipeout)
{
/*
@@ -469,8 +472,7 @@ update_fileproc (finfo)
#ifdef SERVER_SUPPORT
case T_PATCH: /* needs patch */
#endif
- retval = checkout_file (finfo->file, finfo->repository, finfo->entries, finfo->rcs,
- vers, finfo->update_dir);
+ retval = checkout_file (finfo, vers, 0);
break;
default: /* can't ever happen :-) */
@@ -504,11 +506,10 @@ update_fileproc (finfo)
if (wrap_merge_is_copy (finfo->file))
/* Should we be warning the user that we are
* overwriting the user's copy of the file? */
- retval = checkout_file (finfo->file, finfo->repository, finfo->entries,
- finfo->rcs, vers, finfo->update_dir);
+ retval =
+ checkout_file (finfo, vers, 0);
else
- retval = merge_file (finfo->file, finfo->repository, finfo->entries,
- vers, finfo->update_dir);
+ retval = merge_file (finfo, vers);
}
break;
case T_MODIFIED: /* locally modified */
@@ -578,13 +579,13 @@ update_fileproc (finfo)
struct stat file_info;
unsigned char checksum[16];
- retval = patch_file (finfo->file, finfo->repository, finfo->entries, finfo->rcs,
- vers, finfo->update_dir, &docheckout,
+ retval = patch_file (finfo,
+ vers, &docheckout,
&file_info, checksum);
if (! docheckout)
{
if (server_active && retval == 0)
- server_updated (finfo->file, finfo->update_dir, finfo->repository,
+ server_updated (finfo, vers,
SERVER_PATCHED, &file_info,
checksum);
break;
@@ -597,11 +598,10 @@ update_fileproc (finfo)
/* Fall through. */
#endif
case T_CHECKOUT: /* needs checkout */
- retval = checkout_file (finfo->file, finfo->repository, finfo->entries, finfo->rcs,
- vers, finfo->update_dir);
+ retval = checkout_file (finfo, vers, 0);
#ifdef SERVER_SUPPORT
if (server_active && retval == 0)
- server_updated (finfo->file, finfo->update_dir, finfo->repository,
+ server_updated (finfo, vers,
SERVER_UPDATED, (struct stat *) NULL,
(unsigned char *) NULL);
#endif
@@ -613,12 +613,16 @@ update_fileproc (finfo)
retval = write_letter (finfo->file, 'R', finfo->update_dir);
break;
case T_REMOVE_ENTRY: /* needs to be un-registered */
- retval = scratch_file (finfo->file, finfo->repository, finfo->entries, finfo->update_dir);
+ retval = scratch_file (finfo);
#ifdef SERVER_SUPPORT
if (server_active && retval == 0)
- server_updated (finfo->file, finfo->update_dir, finfo->repository,
+ {
+ if (vers->ts_user == NULL)
+ server_scratch_entry_only ();
+ server_updated (finfo, vers,
SERVER_UPDATED, (struct stat *) NULL,
(unsigned char *) NULL);
+ }
#endif
break;
default: /* can't ever happen :-) */
@@ -631,11 +635,7 @@ update_fileproc (finfo)
/* only try to join if things have gone well thus far */
if (retval == 0 && join_rev1)
-#ifdef SERVER_SUPPORT
- join_file (finfo->file, finfo->rcs, vers, finfo->update_dir, finfo->entries, finfo->repository);
-#else
- join_file (finfo->file, finfo->rcs, vers, finfo->update_dir, finfo->entries);
-#endif
+ join_file (finfo, vers);
/* if this directory has an ignore list, add this file to it */
if (ignlist)
@@ -665,15 +665,17 @@ update_ignproc (file, dir)
/* ARGSUSED */
static int
-update_filesdone_proc (err, repository, update_dir)
+update_filesdone_proc (callerdat, err, repository, update_dir, entries)
+ void *callerdat;
int err;
char *repository;
char *update_dir;
+ List *entries;
{
/* if this directory has an ignore list, process it then free it */
if (ignlist)
{
- ignore_files (ignlist, update_dir, update_ignproc);
+ ignore_files (ignlist, entries, update_dir, update_ignproc);
dellist (&ignlist);
}
@@ -694,7 +696,7 @@ update_filesdone_proc (err, repository, update_dir)
{
/* If there is no CVS/Root file, add one */
if (!isfile (CVSADM_ROOT))
- Create_Root( (char *) NULL, CVSroot );
+ Create_Root ((char *) NULL, CVSroot_original);
}
return (err);
@@ -709,18 +711,20 @@ update_filesdone_proc (err, repository, update_dir)
* recursion code should skip this directory.
*/
static Dtype
-update_dirent_proc (dir, repository, update_dir)
+update_dirent_proc (callerdat, dir, repository, update_dir, entries)
+ void *callerdat;
char *dir;
char *repository;
char *update_dir;
+ List *entries;
{
if (ignore_directory (update_dir))
- {
+ {
/* print the warm fuzzy message */
if (!quiet)
error (0, 0, "Ignoring %s", update_dir);
return R_SKIP_ALL;
- }
+ }
if (!isdir (dir))
{
@@ -739,6 +743,7 @@ update_dirent_proc (dir, repository, update_dir)
/* otherwise, create the dir and appropriate adm files */
make_directory (dir);
Create_Admin (dir, update_dir, repository, tag, date);
+ Subdir_Register (entries, (char *) NULL, dir);
}
}
/* Do we need to check noexec here? */
@@ -812,16 +817,18 @@ update_dirent_proc (dir, repository, update_dir)
*/
/* ARGSUSED */
static int
-update_dirleave_proc (dir, err, update_dir)
+update_dirleave_proc (callerdat, dir, err, update_dir, entries)
+ void *callerdat;
char *dir;
int err;
char *update_dir;
+ List *entries;
{
FILE *fp;
/* run the update_prog if there is one */
if (err == 0 && !pipeout && !noexec &&
- (fp = fopen (CVSADM_UPROG, "r")) != NULL)
+ (fp = CVS_FOPEN (CVSADM_UPROG, "r")) != NULL)
{
char *cp;
char *repository;
@@ -842,16 +849,20 @@ update_dirleave_proc (dir, err, update_dir)
free (repository);
}
- /* FIXME: chdir ("..") loses with symlinks. */
- /* Prune empty dirs on the way out - if necessary */
- (void) chdir ("..");
- if (update_prune_dirs && isemptydir (dir))
+ if (strchr (dir, '/') == NULL)
{
- /* I'm not sure the existence_error is actually possible (except
- in cases where we really should print a message), but since
- this code used to ignore all errors, I'll play it safe. */
- if (unlink_file_dir (dir) < 0 && !existence_error (errno))
- error (0, errno, "cannot remove %s directory", dir);
+ /* FIXME: chdir ("..") loses with symlinks. */
+ /* Prune empty dirs on the way out - if necessary */
+ (void) CVS_CHDIR ("..");
+ if (update_prune_dirs && isemptydir (dir))
+ {
+ /* I'm not sure the existence_error is actually possible (except
+ in cases where we really should print a message), but since
+ this code used to ignore all errors, I'll play it safe. */
+ if (unlink_file_dir (dir) < 0 && !existence_error (errno))
+ error (0, errno, "cannot remove %s directory", dir);
+ Subdir_Deregister (entries, (char *) NULL, dir);
+ }
}
return (err);
@@ -868,7 +879,7 @@ isemptydir (dir)
DIR *dirp;
struct dirent *dp;
- if ((dirp = opendir (dir)) == NULL)
+ if ((dirp = CVS_OPENDIR (dir)) == NULL)
{
error (0, 0, "cannot open directory %s for empty check", dir);
return (0);
@@ -890,29 +901,24 @@ isemptydir (dir)
* scratch the Entries file entry associated with a file
*/
static int
-scratch_file (file, repository, entries, update_dir)
- char *file;
- char *repository;
- List *entries;
- char *update_dir;
+scratch_file (finfo)
+ struct file_info *finfo;
{
- history_write ('W', update_dir, "", file, repository);
- Scratch_Entry (entries, file);
- (void) unlink_file (file);
+ history_write ('W', finfo->update_dir, "", finfo->file, finfo->repository);
+ Scratch_Entry (finfo->entries, finfo->file);
+ if (unlink_file (finfo->file) < 0 && ! existence_error (errno))
+ error (0, errno, "unable to remove %s", finfo->fullname);
return (0);
}
/*
- * check out a file - essentially returns the result of the fork on "co".
+ * Check out a file.
*/
static int
-checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
- char *file;
- char *repository;
- List *entries;
- RCSNode *rcsnode;
+checkout_file (finfo, vers_ts, adding)
+ struct file_info *finfo;
Vers_TS *vers_ts;
- char *update_dir;
+ int adding;
{
char backup[PATH_MAX];
int set_time, retval = 0;
@@ -923,9 +929,9 @@ checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
/* don't screw with backup files if we're going to stdout */
if (!pipeout)
{
- (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, file);
- if (isfile (file))
- rename_file (file, backup);
+ (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
+ if (isfile (finfo->file))
+ rename_file (finfo->file, backup);
else
(void) unlink_file (backup);
}
@@ -943,73 +949,28 @@ checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
{
(void) fprintf (stderr, "\
===================================================================\n");
- if (update_dir[0])
- (void) fprintf (stderr, "Checking out %s/%s\n",
- update_dir, file);
- else
- (void) fprintf (stderr, "Checking out %s\n", file);
+ (void) fprintf (stderr, "Checking out %s\n", finfo->fullname);
(void) fprintf (stderr, "RCS: %s\n", vers_ts->srcfile->path);
(void) fprintf (stderr, "VERS: %s\n", vers_ts->vn_rcs);
(void) fprintf (stderr, "***************\n");
}
}
- status = RCS_checkout (vers_ts->srcfile->path,
- pipeout ? NULL : file, vers_ts->vn_tag,
- vers_ts->options, RUN_TTY, 0, 0);
+ status = RCS_checkout (vers_ts->srcfile,
+ pipeout ? NULL : finfo->file,
+ vers_ts->vn_rcs, vers_ts->vn_tag,
+ vers_ts->options, RUN_TTY);
}
if (file_is_dead || status == 0)
{
if (!pipeout)
{
Vers_TS *xvers_ts;
- int resurrecting;
-
- resurrecting = 0;
-
- if (file_is_dead && joining())
- {
- if (RCS_getversion (vers_ts->srcfile, join_rev1,
- date_rev1, 1, 0)
- || (join_rev2 != NULL &&
- RCS_getversion (vers_ts->srcfile, join_rev2,
- date_rev2, 1, 0)))
- {
- /* when joining, we need to get dead files checked
- out. Try harder. */
- /* I think that RCS_FLAGS_FORCE is here only because
- passing -f to co used to enable checking out
- a dead revision in the old version of death
- support which used a hacked RCS instead of using
- the RCS state. */
- retcode = RCS_checkout (vers_ts->srcfile->path, file,
- vers_ts->vn_rcs,
- vers_ts->options, RUN_TTY,
- RCS_FLAGS_FORCE, 0);
- if (retcode != 0)
- {
- error (retcode == -1 ? 1 : 0,
- retcode == -1 ? errno : 0,
- "could not check out %s", file);
- (void) unlink_file (backup);
- return (retcode);
- }
- file_is_dead = 0;
- resurrecting = 1;
- }
- else
- {
- /* If the file is dead and does not contain either of
- the join revisions, then we don't want to check it
- out. */
- return 0;
- }
- }
if (cvswrite == TRUE
&& !file_is_dead
- && !fileattr_get (file, "_watched"))
- xchmod (file, 1);
+ && !fileattr_get (finfo->file, "_watched"))
+ xchmod (finfo->file, 1);
{
/* A newly checked out file is never under the spell
@@ -1020,11 +981,11 @@ checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
struct addremove_args args;
- editor_set (file, getcaller (), NULL);
+ editor_set (finfo->file, getcaller (), NULL);
memset (&args, 0, sizeof args);
args.remove_temp = 1;
- watch_modify_watchers (file, &args);
+ watch_modify_watchers (finfo->file, &args);
}
/* set the time from the RCS file iff it was unknown before */
@@ -1036,10 +997,10 @@ checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
else
set_time = 0;
- wrap_fromcvs_process_file (file);
+ wrap_fromcvs_process_file (finfo->file);
- xvers_ts = Version_TS (repository, options, tag, date, file,
- force_tag_match, set_time, entries, rcsnode);
+ xvers_ts = Version_TS (finfo, options, tag, date,
+ force_tag_match, set_time);
if (strcmp (xvers_ts->options, "-V4") == 0)
xvers_ts->options[0] = '\0';
@@ -1049,31 +1010,31 @@ checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
{
if (xvers_ts->vn_user != NULL)
{
- if (update_dir[0] == '\0')
- error (0, 0,
- "warning: %s is not (any longer) pertinent",
- file);
- else
- error (0, 0,
- "warning: %s/%s is not (any longer) pertinent",
- update_dir, file);
+ error (0, 0,
+ "warning: %s is not (any longer) pertinent",
+ finfo->fullname);
}
- Scratch_Entry (entries, file);
- if (unlink_file (file) < 0 && ! existence_error (errno))
+ Scratch_Entry (finfo->entries, finfo->file);
+#ifdef SERVER_SUPPORT
+ if (server_active && xvers_ts->ts_user == NULL)
+ server_scratch_entry_only ();
+#endif
+ /* FIXME: Rather than always unlink'ing, and ignoring the
+ existence_error, we should do the unlink only if
+ vers_ts->ts_user is non-NULL. Then there would be no
+ need to ignore an existence_error (for example, if the
+ user removes the file while we are running). */
+ if (unlink_file (finfo->file) < 0 && ! existence_error (errno))
{
- if (update_dir[0] == '\0')
- error (0, errno, "cannot remove %s", file);
- else
- error (0, errno, "cannot remove %s/%s", update_dir,
- file);
+ error (0, errno, "cannot remove %s", finfo->fullname);
}
}
else
- Register (entries, file,
- resurrecting ? "0" : xvers_ts->vn_rcs,
- xvers_ts->ts_user, xvers_ts->options,
- xvers_ts->tag, xvers_ts->date,
- (char *)0); /* Clear conflict flag on fresh checkout */
+ Register (finfo->entries, finfo->file,
+ adding ? "0" : xvers_ts->vn_rcs,
+ xvers_ts->ts_user, xvers_ts->options,
+ xvers_ts->tag, xvers_ts->date,
+ (char *)0); /* Clear conflict flag on fresh checkout */
/* fix up the vers structure, in case it is used by join */
if (join_rev1)
@@ -1088,14 +1049,14 @@ checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
/* If this is really Update and not Checkout, recode history */
if (strcmp (command_name, "update") == 0)
- history_write ('U', update_dir, xvers_ts->vn_rcs, file,
- repository);
+ history_write ('U', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
+ finfo->repository);
freevers_ts (&xvers_ts);
if (!really_quiet && !file_is_dead)
{
- write_letter (file, 'U', update_dir);
+ write_letter (finfo->file, 'U', finfo->update_dir);
}
}
}
@@ -1104,10 +1065,10 @@ checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
int old_errno = errno; /* save errno value over the rename */
if (!pipeout && isfile (backup))
- rename_file (backup, file);
+ rename_file (backup, finfo->file);
error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
- "could not check out %s", file);
+ "could not check out %s", finfo->fullname);
retval = retcode;
}
@@ -1124,14 +1085,9 @@ checkout_file (file, repository, entries, rcsnode, vers_ts, update_dir)
* itself.
*/
static int
-patch_file (file, repository, entries, rcsnode, vers_ts, update_dir,
- docheckout, file_info, checksum)
- char *file;
- char *repository;
- List *entries;
- RCSNode *rcsnode;
+patch_file (finfo, vers_ts, docheckout, file_info, checksum)
+ struct file_info *finfo;
Vers_TS *vers_ts;
- char *update_dir;
int *docheckout;
struct stat *file_info;
unsigned char *checksum;
@@ -1153,14 +1109,14 @@ patch_file (file, repository, entries, rcsnode, vers_ts, update_dir,
return 0;
}
- (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, file);
- if (isfile (file))
- rename_file (file, backup);
+ (void) sprintf (backup, "%s/%s%s", CVSADM, CVSPREFIX, finfo->file);
+ if (isfile (finfo->file))
+ rename_file (finfo->file, backup);
else
(void) unlink_file (backup);
- (void) sprintf (file1, "%s/%s%s-1", CVSADM, CVSPREFIX, file);
- (void) sprintf (file2, "%s/%s%s-2", CVSADM, CVSPREFIX, file);
+ (void) sprintf (file1, "%s/%s%s-1", CVSADM, CVSPREFIX, finfo->file);
+ (void) sprintf (file2, "%s/%s%s-2", CVSADM, CVSPREFIX, finfo->file);
fail = 0;
@@ -1170,14 +1126,14 @@ patch_file (file, repository, entries, rcsnode, vers_ts, update_dir,
if (noexec)
retcode = 0;
else
- retcode = RCS_checkout (vers_ts->srcfile->path, NULL,
- vers_ts->vn_user,
- vers_ts->options, file1, 0, 0);
+ retcode = RCS_checkout (vers_ts->srcfile, (char *) NULL,
+ vers_ts->vn_user, (char *) NULL,
+ vers_ts->options, file1);
if (retcode != 0)
fail = 1;
else
{
- e = fopen (file1, "r");
+ e = CVS_FOPEN (file1, "r");
if (e == NULL)
fail = 1;
else
@@ -1193,29 +1149,29 @@ patch_file (file, repository, entries, rcsnode, vers_ts, update_dir,
if (! fail)
{
- /* Check it out into file, and then move to file2, so that we
+ /* Check it out into finfo->file, and then move to file2, so that we
can get the right modes into *FILE_INFO. We can't check it
out directly into file2 because co doesn't understand how
to do that. */
- retcode = RCS_checkout (vers_ts->srcfile->path, file,
- vers_ts->vn_rcs,
- vers_ts->options, RUN_TTY, 0, 0);
+ retcode = RCS_checkout (vers_ts->srcfile, finfo->file,
+ vers_ts->vn_rcs, (char *) NULL,
+ vers_ts->options, RUN_TTY);
if (retcode != 0)
fail = 1;
else
{
- if (!isreadable (file))
+ if (!isreadable (finfo->file))
{
/* File is dead. */
fail = 1;
}
else
{
- rename_file (file, file2);
+ rename_file (finfo->file, file2);
if (cvswrite == TRUE
- && !fileattr_get (file, "_watched"))
+ && !fileattr_get (finfo->file, "_watched"))
xchmod (file2, 1);
- e = fopen (file2, "r");
+ e = CVS_FOPEN (file2, "r");
if (e == NULL)
fail = 1;
else
@@ -1266,7 +1222,7 @@ patch_file (file, repository, entries, rcsnode, vers_ts, update_dir,
run_setup ("%s -c %s %s", DIFF, file1, file2);
/* A retcode of 0 means no differences. 1 means some differences. */
- if ((retcode = run_exec (RUN_TTY, file, RUN_TTY, RUN_NORMAL)) != 0
+ if ((retcode = run_exec (RUN_TTY, finfo->file, RUN_TTY, RUN_NORMAL)) != 0
&& retcode != 1)
{
fail = 1;
@@ -1278,9 +1234,10 @@ patch_file (file, repository, entries, rcsnode, vers_ts, update_dir,
unsigned int c;
/* Check the diff output to make sure patch will be handle it. */
- e = fopen (file, "r");
+ e = CVS_FOPEN (finfo->file, "r");
if (e == NULL)
- error (1, errno, "could not open diff output file %s", file);
+ error (1, errno, "could not open diff output file %s",
+ finfo->fullname);
c = fread (buf, 1, sizeof BINARY - 1, e);
buf[c] = '\0';
if (strcmp (buf, BINARY) == 0)
@@ -1309,28 +1266,28 @@ patch_file (file, repository, entries, rcsnode, vers_ts, update_dir,
/* This stuff is just copied blindly from checkout_file. I
don't really know what it does. */
- xvers_ts = Version_TS (repository, options, tag, date, file,
- force_tag_match, 0, entries, rcsnode);
+ xvers_ts = Version_TS (finfo, options, tag, date,
+ force_tag_match, 0);
if (strcmp (xvers_ts->options, "-V4") == 0)
xvers_ts->options[0] = '\0';
- Register (entries, file, xvers_ts->vn_rcs,
+ Register (finfo->entries, finfo->file, xvers_ts->vn_rcs,
xvers_ts->ts_user, xvers_ts->options,
xvers_ts->tag, xvers_ts->date, NULL);
- if (stat (file2, file_info) < 0)
+ if ( CVS_STAT (file2, file_info) < 0)
error (1, errno, "could not stat %s", file2);
/* If this is really Update and not Checkout, recode history */
if (strcmp (command_name, "update") == 0)
- history_write ('P', update_dir, xvers_ts->vn_rcs, file,
- repository);
+ history_write ('P', finfo->update_dir, xvers_ts->vn_rcs, finfo->file,
+ finfo->repository);
freevers_ts (&xvers_ts);
if (!really_quiet)
{
- write_letter (file, 'P', update_dir);
+ write_letter (finfo->file, 'P', finfo->update_dir);
}
}
else
@@ -1338,11 +1295,11 @@ patch_file (file, repository, entries, rcsnode, vers_ts, update_dir,
int old_errno = errno; /* save errno value over the rename */
if (isfile (backup))
- rename_file (backup, file);
+ rename_file (backup, finfo->file);
if (retcode != 0 && retcode != 1)
error (retcode == -1 ? 1 : 0, retcode == -1 ? old_errno : 0,
- "could not diff %s", file);
+ "could not diff %s", finfo->fullname);
*docheckout = 1;
retval = retcode;
@@ -1387,14 +1344,10 @@ write_letter (file, letter, update_dir)
* Do all the magic associated with a file which needs to be merged
*/
static int
-merge_file (file, repository, entries, vers, update_dir)
- char *file;
- char *repository;
- List *entries;
+merge_file (finfo, vers)
+ struct file_info *finfo;
Vers_TS *vers;
- char *update_dir;
{
- char user[PATH_MAX];
char backup[PATH_MAX];
int status;
int retcode = 0;
@@ -1406,25 +1359,50 @@ merge_file (file, repository, entries, vers, update_dir)
* is the version of the file that the user was most up-to-date with
* before the merge.
*/
- (void) sprintf (backup, "%s%s.%s", BAKPREFIX, file, vers->vn_user);
- if (update_dir[0])
- (void) sprintf (user, "%s/%s", update_dir, file);
- else
- (void) strcpy (user, file);
+ (void) sprintf (backup, "%s%s.%s", BAKPREFIX, finfo->file, vers->vn_user);
(void) unlink_file (backup);
- copy_file (file, backup);
- xchmod (file, 1);
+ copy_file (finfo->file, backup);
+ xchmod (finfo->file, 1);
+
+ if (strcmp (vers->options, "-kb") == 0)
+ {
+ /* For binary files, a merge is always a conflict. We give the
+ user the two files, and let them resolve it. It is possible
+ that we should require a "touch foo" or similar step before
+ we allow a checkin. */
+ status = checkout_file (finfo, vers, 0);
+#ifdef SERVER_SUPPORT
+ /* Send the new contents of the file before the message. If we
+ wanted to be totally correct, we would have the client write
+ the message only after the file has safely been written. */
+ if (server_active)
+ {
+ server_copy_file (finfo->file, finfo->update_dir,
+ finfo->repository, backup);
+ server_updated (finfo, vers, SERVER_MERGED,
+ (struct stat *) NULL, (unsigned char *) NULL);
+ }
+#endif
+ error (0, 0, "binary file needs merge");
+ error (0, 0, "revision %s from repository is now in %s",
+ vers->vn_rcs, finfo->fullname);
+ error (0, 0, "file from working directory is now in %s", backup);
+ write_letter (finfo->file, 'C', finfo->update_dir);
+
+ history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file, finfo->repository);
+ return 0;
+ }
status = RCS_merge(vers->srcfile->path,
vers->options, vers->vn_user, vers->vn_rcs);
if (status != 0 && status != 1)
{
error (0, status == -1 ? errno : 0,
- "could not merge revision %s of %s", vers->vn_user, user);
+ "could not merge revision %s of %s", vers->vn_user, finfo->fullname);
error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
- user, backup);
- rename_file (backup, file);
+ finfo->fullname, backup);
+ rename_file (backup, finfo->file);
return (1);
}
@@ -1435,8 +1413,8 @@ merge_file (file, repository, entries, vers, update_dir)
char *cp = 0;
if (status)
- cp = time_stamp (file);
- Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options,
+ cp = time_stamp (finfo->file);
+ Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_rcs, vers->options,
vers->tag, vers->date, cp);
if (cp)
free (cp);
@@ -1456,38 +1434,39 @@ merge_file (file, repository, entries, vers, update_dir)
the message only after the file has safely been written. */
if (server_active)
{
- server_copy_file (file, update_dir, repository, backup);
- server_updated (file, update_dir, repository, SERVER_MERGED,
+ server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
+ backup);
+ server_updated (finfo, vers, SERVER_MERGED,
(struct stat *) NULL, (unsigned char *) NULL);
}
#endif
- if (!noexec && !xcmp (backup, file))
+ if (!noexec && !xcmp (backup, finfo->file))
{
printf ("%s already contains the differences between %s and %s\n",
- user, vers->vn_user, vers->vn_rcs);
- history_write ('G', update_dir, vers->vn_rcs, file, repository);
+ finfo->fullname, vers->vn_user, vers->vn_rcs);
+ history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file, finfo->repository);
return (0);
}
if (status == 1)
{
if (!noexec)
- error (0, 0, "conflicts found in %s", user);
+ error (0, 0, "conflicts found in %s", finfo->fullname);
- write_letter (file, 'C', update_dir);
+ write_letter (finfo->file, 'C', finfo->update_dir);
- history_write ('C', update_dir, vers->vn_rcs, file, repository);
+ history_write ('C', finfo->update_dir, vers->vn_rcs, finfo->file, finfo->repository);
}
else if (retcode == -1)
{
- error (1, errno, "fork failed while examining update of %s", user);
+ error (1, errno, "fork failed while examining update of %s", finfo->fullname);
}
else
{
- write_letter (file, 'M', update_dir);
- history_write ('G', update_dir, vers->vn_rcs, file, repository);
+ write_letter (finfo->file, 'M', finfo->update_dir);
+ history_write ('G', finfo->update_dir, vers->vn_rcs, finfo->file, finfo->repository);
}
return (0);
}
@@ -1497,19 +1476,10 @@ merge_file (file, repository, entries, vers, update_dir)
* (-j option)
*/
static void
-#ifdef SERVER_SUPPORT
-join_file (file, rcsnode, vers, update_dir, entries, repository)
- char *repository;
-#else
-join_file (file, rcsnode, vers, update_dir, entries)
-#endif
- char *file;
- RCSNode *rcsnode;
+join_file (finfo, vers)
+ struct file_info *finfo;
Vers_TS *vers;
- char *update_dir;
- List *entries;
{
- char user[PATH_MAX];
char backup[PATH_MAX];
char *options;
int status;
@@ -1526,24 +1496,23 @@ join_file (file, rcsnode, vers, update_dir, entries)
jdate1 = date_rev1;
jdate2 = date_rev2;
- if (wrap_merge_is_copy (file))
+ if (wrap_merge_is_copy (finfo->file))
{
- /* FIXME: Should be including update_dir in message. */
error (0, 0,
- "Cannot merge %s because it is a merge-by-copy file.", file);
+ "Cannot merge %s because it is a merge-by-copy file.",
+ finfo->fullname);
return;
}
- /* determine if we need to do anything at all */
+ /* Determine if we need to do anything at all. */
if (vers->srcfile == NULL ||
vers->srcfile->path == NULL)
{
return;
}
- /* in all cases, use two revs. */
-
- /* if only one rev is specified, it becomes the second rev */
+ /* If only one join revision is specified, it becomes the second
+ revision. */
if (jrev2 == NULL)
{
jrev2 = jrev1;
@@ -1552,219 +1521,281 @@ join_file (file, rcsnode, vers, update_dir, entries)
jdate1 = NULL;
}
- /* The file in the working directory doesn't exist in CVS/Entries.
- FIXME: Shouldn't this case result in additional processing (if
- the file was added going from rev1 to rev2, then do the equivalent
- of a "cvs add")? (yes; easier said than done.. :-) */
- if (vers->vn_user == NULL)
+ /* Convert the second revision, walking branches and dates. */
+ rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, (int *) NULL);
+
+ /* If this is a merge of two revisions, get the first revision.
+ If only one join tag was specified, then the first revision is
+ the greatest common ancestor of the second revision and the
+ working file. */
+ if (jrev1 != NULL)
+ rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1, (int *) NULL);
+ else
{
- /* No merge possible YET. */
- if (jdate2 != NULL)
- error (0, 0,
- "file %s is present in revision %s as of %s",
- file, jrev2, jdate2);
+ /* Note that we use vn_rcs here, since vn_user may contain a
+ special string such as "-nn". */
+ if (vers->vn_rcs == NULL)
+ rev1 = NULL;
+ else if (rev2 == NULL)
+ {
+ /* This means that the file never existed on the branch.
+ It does not mean that the file was removed on the
+ branch: that case is represented by a dead rev2. If
+ the file never existed on the branch, then we have
+ nothing to merge, so we just return. */
+ return;
+ }
else
- error (0, 0,
- "file %s is present in revision %s",
- file, jrev2);
- return;
+ rev1 = gca (vers->vn_rcs, rev2);
}
- /* Fix for bug CVS/193:
- * Used to dump core if the file had been removed on the current branch.
- */
- if (strcmp(vers->vn_user, "0") == 0)
+ /* Handle a nonexistent or dead merge target. */
+ if (rev2 == NULL || RCS_isdead (vers->srcfile, rev2))
{
- error(0, 0,
- "file %s has been deleted",
- file);
- return;
- }
+ char *mrev;
- /* convert the second rev spec, walking branches and dates. */
+ if (rev2 != NULL)
+ free (rev2);
- rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1, 0);
- if (rev2 == NULL)
- {
- if (!quiet)
+ /* If the first revision doesn't exist either, then there is
+ no change between the two revisions, so we don't do
+ anything. */
+ if (rev1 == NULL || RCS_isdead (vers->srcfile, rev1))
+ {
+ if (rev1 != NULL)
+ free (rev1);
+ return;
+ }
+
+ /* If we are merging two revisions, then the file was removed
+ between the first revision and the second one. In this
+ case we want to mark the file for removal.
+
+ If we are merging one revision, then the file has been
+ removed between the greatest common ancestor and the merge
+ revision. From the perspective of the branch on to which
+ we ar emerging, which may be the trunk, either 1) the file
+ does not currently exist on the target, or 2) the file has
+ not been modified on the target branch since the greatest
+ common ancestor, or 3) the file has been modified on the
+ target branch since the greatest common ancestor. In case
+ 1 there is nothing to do. In case 2 we mark the file for
+ removal. In case 3 we have a conflict.
+
+ Note that the handling is slightly different depending upon
+ whether one or two join targets were specified. If two
+ join targets were specified, we don't check whether the
+ file was modified since a given point. My reasoning is
+ that if you ask for an explicit merge between two tags,
+ then you want to merge in whatever was changed between
+ those two tags. If a file was removed between the two
+ tags, then you want it to be removed. However, if you ask
+ for a merge of a branch, then you want to merge in all
+ changes which were made on the branch. If a file was
+ removed on the branch, that is a change to the file. If
+ the file was also changed on the main line, then that is
+ also a change. These two changes--the file removal and the
+ modification--must be merged. This is a conflict. */
+
+ /* If the user file is dead, or does not exist, or has been
+ marked for removal, then there is nothing to do. */
+ if (vers->vn_user == NULL
+ || vers->vn_user[0] == '-'
+ || RCS_isdead (vers->srcfile, vers->vn_user))
+ {
+ if (rev1 != NULL)
+ free (rev1);
+ return;
+ }
+
+ /* If the user file has been marked for addition, or has been
+ locally modified, then we have a conflict which we can not
+ resolve. No_Difference will already have been called in
+ this case, so comparing the timestamps is sufficient to
+ determine whether the file is locally modified. */
+ if (strcmp (vers->vn_user, "0") == 0
+ || (vers->ts_user != NULL
+ && strcmp (vers->ts_user, vers->ts_rcs) != 0))
+ {
+ if (jdate2 != NULL)
+ error (0, 0,
+ "file %s is locally modified, but has been removed in revision %s as of %s",
+ finfo->fullname, jrev2, jdate2);
+ else
+ error (0, 0,
+ "file %s is locally modified, but has been removed in revision %s",
+ finfo->fullname, jrev2);
+
+ /* FIXME: Should we arrange to return a non-zero exit
+ status? */
+
+ if (rev1 != NULL)
+ free (rev1);
+
+ return;
+ }
+
+ /* If only one join tag was specified, and the user file has
+ been changed since the greatest common ancestor (rev1),
+ then there is a conflict we can not resolve. See above for
+ the rationale. */
+ if (join_rev2 == NULL
+ && strcmp (rev1, vers->vn_user) != 0)
{
if (jdate2 != NULL)
error (0, 0,
- "cannot find revision %s as of %s in file %s",
- jrev2, jdate2, file);
+ "file %s has been modified, but has been removed in revision %s as of %s",
+ finfo->fullname, jrev2, jdate2);
else
error (0, 0,
- "cannot find revision %s in file %s",
- jrev2, file);
+ "file %s has been modified, but has been removed in revision %s",
+ finfo->fullname, jrev2);
+
+ /* FIXME: Should we arrange to return a non-zero exit
+ status? */
+
+ if (rev1 != NULL)
+ free (rev1);
+
+ return;
+ }
+
+ if (rev1 != NULL)
+ free (rev1);
+
+ /* The user file exists and has not been modified. Mark it
+ for removal. FIXME: If we are doing a checkout, this has
+ the effect of first checking out the file, and then
+ removing it. It would be better to just register the
+ removal. */
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ {
+ server_scratch (finfo->file);
+ server_updated (finfo, vers, SERVER_UPDATED, (struct stat *) NULL,
+ (unsigned char *) NULL);
}
+#endif
+ mrev = xmalloc (strlen (vers->vn_user) + 2);
+ sprintf (mrev, "-%s", vers->vn_user);
+ Register (finfo->entries, finfo->file, mrev, vers->ts_rcs,
+ vers->options, vers->tag, vers->date, vers->ts_conflict);
+ free (mrev);
+ /* We need to check existence_error here because if we are
+ running as the server, and the file is up to date in the
+ working directory, the client will not have sent us a copy. */
+ if (unlink_file (finfo->file) < 0 && ! existence_error (errno))
+ error (0, errno, "cannot remove file %s", finfo->fullname);
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ server_checked_in (finfo->file, finfo->update_dir,
+ finfo->repository);
+#endif
+ if (! really_quiet)
+ error (0, 0, "scheduling %s for removal", finfo->fullname);
+
return;
}
- /* skip joining identical revs */
- if (strcmp (rev2, vers->vn_user) == 0)
+ /* If the target of the merge is the same as the working file
+ revision, then there is nothing to do. */
+ if (vers->vn_user != NULL && strcmp (rev2, vers->vn_user) == 0)
{
- /* No merge necessary. */
+ if (rev1 != NULL)
+ free (rev1);
free (rev2);
return;
}
- if (jrev1 == NULL)
+ /* If rev1 is dead or does not exist, then the file was added
+ between rev1 and rev2. */
+ if (rev1 == NULL || RCS_isdead (vers->srcfile, rev1))
{
- char *tst;
- /* if the first rev is missing, then it is implied to be the
- greatest common ancestor of both the join rev, and the
- checked out rev. */
-
- /* FIXME: What is this check for '!' about? If it is legal to
- have '!' in the first character of vn_user, it isn't
- documented at struct vers_ts in cvs.h. */
- tst = vers->vn_user;
- if (*tst == '!')
- {
- /* file was dead. merge anyway and pretend it's been
- added. */
- ++tst;
- Register (entries, file, "0", vers->ts_user, vers->options,
- vers->tag, (char *) 0, (char *) 0);
- }
- rev1 = gca (tst, rev2);
- if (rev1 == NULL)
- {
- /* this should not be possible */
- error (0, 0, "bad gca");
- abort();
- }
+ if (rev1 != NULL)
+ free (rev1);
+ free (rev2);
- tst = RCS_gettag (vers->srcfile, rev2, 1, 0);
- if (tst == NULL)
+ /* If the file does not exist in the working directory, then
+ we can just check out the new revision and mark it for
+ addition. */
+ if (vers->vn_user == NULL)
{
- /* this should not be possible. */
- error (0, 0, "cannot find gca");
- abort();
- }
+ Vers_TS *xvers;
- free (tst);
+ xvers = Version_TS (finfo, vers->options, jrev2, jdate2, 1, 0);
+
+ /* FIXME: If checkout_file fails, we should arrange to
+ return a non-zero exit status. */
+ status = checkout_file (finfo, xvers, 1);
+
+#ifdef SERVER_SUPPORT
+ if (server_active && status == 0)
+ server_updated (finfo, xvers,
+ SERVER_UPDATED, (struct stat *) NULL,
+ (unsigned char *) NULL);
+#endif
+
+ freevers_ts (&xvers);
- /* these two cases are noops */
- if (strcmp (rev1, rev2) == 0)
- {
- free (rev1);
- free (rev2);
return;
}
+
+ /* The file currently exists in the working directory, so we
+ have a conflict which we can not resolve. Note that this
+ is true even if the file is marked for addition or removal. */
+
+ if (jdate2 != NULL)
+ error (0, 0,
+ "file %s exists, but has been added in revision %s as of %s",
+ finfo->fullname, jrev2, jdate2);
+ else
+ error (0, 0,
+ "file %s exists, but has been added in revision %s",
+ finfo->fullname, jrev2);
+
+ return;
}
- else
- {
- /* otherwise, convert the first rev spec, walking branches and
- dates. */
- rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1, 0);
- if (rev1 == NULL)
- {
- if (!quiet) {
- if (jdate1 != NULL)
- error (0, 0,
- "cannot find revision %s as of %s in file %s",
- jrev1, jdate1, file);
- else
- error (0, 0,
- "cannot find revision %s in file %s",
- jrev1, file);
- }
- return;
- }
+ /* If the two merge revisions are the same, then there is nothing
+ to do. */
+ if (strcmp (rev1, rev2) == 0)
+ {
+ free (rev1);
+ free (rev2);
+ return;
}
- /* do the join */
+ /* If there is no working file, then we can't do the merge. */
+ if (vers->vn_user == NULL)
+ {
+ free (rev1);
+ free (rev2);
-#if 0
- dome {
- /* special handling when two revisions are specified */
- if (join_rev1 && join_rev2)
- {
- rev = RCS_getversion (vers->srcfile, join_rev2, date_rev2, 1, 0);
- if (rev == NULL)
- {
- if (!quiet && date_rev2 == NULL)
- error (0, 0,
- "cannot find revision %s in file %s", join_rev2, file);
- return;
- }
-
- baserev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1, 0);
- if (baserev == NULL)
- {
- if (!quiet && date_rev1 == NULL)
- error (0, 0,
- "cannot find revision %s in file %s", join_rev1, file);
- free (rev);
- return;
- }
-
- /*
- * nothing to do if:
- * second revision matches our BASE revision (vn_user) &&
- * both revisions are on the same branch
- */
- if (strcmp (vers->vn_user, rev) == 0 &&
- numdots (baserev) == numdots (rev))
- {
- /* might be the same branch. take a real look */
- char *dot = strrchr (baserev, '.');
- int len = (dot - baserev) + 1;
-
- if (strncmp (baserev, rev, len) == 0)
- return;
- }
- }
+ if (jdate2 != NULL)
+ error (0, 0,
+ "file %s is present in revision %s as of %s",
+ finfo->fullname, jrev2, jdate2);
else
- {
- rev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1, 0);
- if (rev == NULL)
- return;
- if (strcmp (rev, vers->vn_user) == 0) /* no merge necessary */
- {
- free (rev);
- return;
- }
-
- baserev = RCS_whatbranch (file, join_rev1, rcsnode);
- if (baserev)
- {
- char *cp;
-
- /* we get a branch -- turn it into a revision, or NULL if trunk */
- if ((cp = strrchr (baserev, '.')) == NULL)
- {
- free (baserev);
- baserev = (char *) NULL;
- }
- else
- *cp = '\0';
- }
- }
- if (baserev && strcmp (baserev, rev) == 0)
- {
- /* they match -> nothing to do */
- free (rev);
- free (baserev);
- return;
- }
- }
-#endif
+ error (0, 0,
+ "file %s is present in revision %s",
+ finfo->fullname, jrev2);
+
+ /* FIXME: Should we arrange to return a non-zero exit status? */
- /* OK, so we have two revisions; continue on */
+ return;
+ }
#ifdef SERVER_SUPPORT
- if (server_active && !isreadable (file))
+ if (server_active && !isreadable (finfo->file))
{
int retcode;
/* The file is up to date. Need to check out the current contents. */
- retcode = RCS_checkout (vers->srcfile->path, "", vers->vn_user, NULL,
- RUN_TTY, 0, 0);
+ retcode = RCS_checkout (vers->srcfile, finfo->file,
+ vers->vn_user, (char *) NULL,
+ (char *) NULL, RUN_TTY);
if (retcode != 0)
error (1, retcode == -1 ? errno : 0,
- "failed to check out %s file", file);
+ "failed to check out %s file", finfo->fullname);
}
#endif
@@ -1775,15 +1806,11 @@ join_file (file, rcsnode, vers, update_dir, entries)
* is the version of the file that the user was most up-to-date with
* before the merge.
*/
- (void) sprintf (backup, "%s%s.%s", BAKPREFIX, file, vers->vn_user);
- if (update_dir[0])
- (void) sprintf (user, "%s/%s", update_dir, file);
- else
- (void) strcpy (user, file);
+ (void) sprintf (backup, "%s%s.%s", BAKPREFIX, finfo->file, vers->vn_user);
(void) unlink_file (backup);
- copy_file (file, backup);
- xchmod (file, 1);
+ copy_file (finfo->file, backup);
+ xchmod (finfo->file, 1);
options = vers->options;
#ifdef HAVE_RCS5
@@ -1797,10 +1824,10 @@ join_file (file, rcsnode, vers, update_dir, entries)
if (status != 0 && status != 1)
{
error (0, status == -1 ? errno : 0,
- "could not merge revision %s of %s", rev2, user);
+ "could not merge revision %s of %s", rev2, finfo->fullname);
error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
- user, backup);
- rename_file (backup, file);
+ finfo->fullname, backup);
+ rename_file (backup, finfo->file);
}
free (rev1);
free (rev2);
@@ -1820,8 +1847,9 @@ join_file (file, rcsnode, vers, update_dir, entries)
char *cp = 0;
if (status)
- cp = time_stamp (file);
- Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options,
+ cp = time_stamp (finfo->file);
+ Register (finfo->entries, finfo->file,
+ vers->vn_rcs, vers->ts_rcs, vers->options,
vers->tag, vers->date, cp);
if (cp)
free(cp);
@@ -1830,8 +1858,9 @@ join_file (file, rcsnode, vers, update_dir, entries)
#ifdef SERVER_SUPPORT
if (server_active)
{
- server_copy_file (file, update_dir, repository, backup);
- server_updated (file, update_dir, repository, SERVER_MERGED,
+ server_copy_file (finfo->file, finfo->update_dir, finfo->repository,
+ backup);
+ server_updated (finfo, vers, SERVER_MERGED,
(struct stat *) NULL, (unsigned char *) NULL);
}
#endif