Import cvs-1.11 onto vendor branch.

This commit is contained in:
Peter Wemm 2000-10-02 06:33:59 +00:00
parent d818196804
commit a3b502f88f
91 changed files with 10860 additions and 6241 deletions

View File

@ -1,3 +1,103 @@
2000-09-07 Larry Jones <larry.jones@sdrc.com>
* Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
from autoconf.
* acconfig.h: Copy HAVE_CRYPT, HAVE_GETSPNAM, REGEX_MALLOC, and
_REGEX_RE_COMP from config.h.in to here, where they should have
been in the first place.
* config.h.in: Regenerated.
2000-08-30 Larry Jones <larry.jones@sdrc.com>
* NEWS: Note additional history enhancements.
2000-08-01 Larry Jones <larry.jones@sdrc.com>
* configure.in, config.h.in: Add check for getpassphrase (Solaris).
* configure: Regenerated.
2000-07-11 Larry Jones <larry.jones@sdrc.com>
* configure.in, config.h.in: Add checks for mknod() and st_rdev
since some systems (notably Plan 9) don't have them.
* configure: Regenerated.
2000-07-10 Larry Jones <larry.jones@sdrc.com>
* NEWS: Note the new "version" command.
2000-07-06 Larry Jones <larry.jones@sdrc.com>
* NEWS: Note that admin -t works in client/server.
2000-06-19 Larry Jones <larry.jones@sdrc.com>
* configure.in (AC_DEFINE): Define REGEX_MALLOC and _REGEX_RE_COMP
to configure lib/regex.c the way we want without messing with the
code.
* config.h.in: Ditto.
* configure: Regenerated.
2000-05-16 Jim Kingdon <kingdon@redhat.com>
* TODO (186): Remove paragraph about Eric Raymond's interest.
This is still on the future projects on his site, it just seems to
brief (and too long ago updated) that I don't really see the need
to mention it.
2000-05-05 Larry Jones <larry.jones@sdrc.com>
* TESTS: Add notes about required tools and where to get them.
2000-05-02 Donald Sharp <sharpd@cisco.com>
and Larry Jones <larry.jones@sdrc.com>
* NEWS: Note history output format change.
2000-02-17 Larry Jones <larry.jones@sdrc.com>
* NEWS: Note that PreservePermissions is disabled.
* configure.in: Don't define PRESERVE_PERMISSIONS_SUPPORT.
* configure: Regenerated.
2000-02-01 Larry Jones <larry.jones@sdrc.com>
* configure.in: Try again to handle systems that need both libsocket
and libnsl.
* configure: Regenerated.
1999-12-09 Larry Jones <larry.jones@sdrc.com>
* configure.in: Correctly handle systems that need both libsocket
and libnsl.
* configure: Regenerated.
1999-12-06 Larry Jones <larry.jones@sdrc.com>
* configure.in: Update to autoconf 2.13; use new AC_SEARCH_LIBS
to handle getspnam, connect, gethostbyname, and crypt correctly;
use new AC_FUNC_FNMATCH instead of doing it by hand.
* configure: Regenerated with autoconf 2.13.
1999-12-06 Larry Jones <larry.jones@sdrc.com>
* INSTALL (Tested platforms): Update info.
1999-11-04 Jim Kingdon <http://developer.redhat.com/>
* README (Installation): Yet another prep.ai.mit.edu -> gnu.org
change (can't believe we still haven't gotten them all).
1999-11-04 Karl Fogel <kfogel@red-bean.com>
* NEWS: added item about anon cvs no longer needing password.
1999-10-28 Larry Jones <larry.jones@sdrc.com>
* TESTS: Add note about not running as root. Remove note about
Solaris sort since sanity.sh was changed to avoid the problem.
1999-07-12 Larry Jones <larry.jones@sdrc.com>
* TESTS: Remove suspicion that setting LC_COLLATE has fixed the

View File

@ -6,7 +6,7 @@ development group operates. Also see the HACKING file.
----------------------------------------------------------------------
Charter for the devel-cvs mailing list:
The CVS Developers' List <devel-cvs@cyclic.com> exists to help people
The CVS Developers' List <devel-cvs@cvshome.org> exists to help people
with access to the CVS source repository co-ordinate changes, make
releases, and administer the repository.

View File

@ -18,6 +18,9 @@ some time, you are encouraged to double-check them against other
sources like the Cederqvist manual and update the FAQ. If you don't
have such time, take them with a grain of salt or a few.
Since Feb. 2000 CVS is being maintained by OpenAvenue, Inc. and many of
the existing resources have been centeralized on http://www.cvshome.org.
Category: /, all questions
Category: /
@ -8554,3 +8557,4 @@ done
The FAQ-O-Matic lives at http://gille.loria.fr:7000/cgi-bin/faqomatic.
The code was written by Jon Howell, and the content by folks from all
over the web.
_________________________________________________________________

View File

@ -191,7 +191,7 @@ Anyone can add themselves to the following mailing lists:
automatically, daily, by a script which runs "make check"
and "make remotecheck" on the master CVS sources.
To subscribe to devel-cvs, commit-cvs, or test-results, send
a message to "majordomo@cyclic.com" whose body consists of
a message to "majordomo@cvshome.org" whose body consists of
"subscribe <list>", where <list> is devel-cvs, commit-cvs or
test-results.

View File

@ -122,7 +122,7 @@ HPPA:
HPPA 1.1 running HP-UX A.09.04 (1.7.1)
HPPA running HP-UX 9.05 (1.9)
HPPA running HP-UX 10.01 (1.7)
HPPA running HP-UX 10.20 (1.9, 1.9.14)
HPPA running HP-UX 10.20 (1.10.7)
NextSTEP 3.3 (1.7)
i386 family:
Solaris 2.4 using gcc (about 1.4A2)
@ -134,7 +134,7 @@ i386 family:
Linux (kernel 1.2.x) (1.8.86)
Linux (kernel 2.0.x, RedHat 4.2) (1.10)
Linux (kernel 2.0.x, RedHat 5.x) (1.10)
BSDI 2.0 (1.4.93) (footnote 5)
BSDI 4.0 (1.10.7)
FreeBSD 2.1.5-stable (1.8.87)
NextSTEP 3.3 (1.7)
SCO Unix 3.2.4.2, gcc 2.7.2 (1.8.87) (footnote 4)
@ -168,11 +168,13 @@ MIPS:
SGI running Irix 6.2 using SGI MIPSpro 6.2 and beta 7.2 compilers (1.9)
SGI running Irix-6.2 (1.9.8)
SGI running IRIX 6.4 (1.10)
SGI running IRIX 6.5 (1.10.7)
Siemens-Nixdorf RM600 running SINIX-Y (1.6)
PowerPC or RS/6000:
IBM RS/6000 running AIX 3.1 using gcc and cc (1.6.86)
IBM RS/6000 running AIX 3.2.5 (1.8)
IBM RS/6000 running AIX 4.1 (1.9)
IBM RS/6000 running AIX 4.3 (1.10.7)
Lynx 2.3.1 120495 (1.6.86) (footnote 9)
Lynx 2.5 (1.9) (footnote 10)
MkLinux DR3 GENERIC #6 (1.10.5.1) (presumably LinuxPPC too)
@ -182,6 +184,7 @@ SPARC:
Sun SPARCstation running Solaris 2.4 using gcc and cc (about 1.5.91)
Sun SPARC running Solaris 2.5 (1.8.87)
Sun SPARC running Solaris 2.5.1 using gcc 2.7.2.2 (1.9.14)
Sun SPARC running Solaris 2.6 (1.10.7)
Sun UltraSPARC running Solaris 2.6 using gcc 2.8.1 (1.10)
NextSTEP 3.3 (1.7)
Sun SPARC running Linux 2.0.17, gcc 2.7.2 (1.8.87)
@ -198,11 +201,6 @@ VAX:
(footnote 4) Comment out the include of sys/time.h in src/server.c. (1.4.93)
You also may have to make sure TIME_WITH_SYS_TIME is undef'ed.
(footnote 5) Change /usr/tmp to /var/tmp in src/server.c (2 places) (1.4.93).
(This should no longer be needed; CVS doesn't have /usr/tmp in
src/server.c any more. Has anyone tried a more recent version
on BSDI? If so, please report it so we can update this file).
(footnote 6) Build in ucb universe with COFF compiler tools. Put
/usr/local/bin first in PATH while doing a configure, make
and install of GNU diffutils-2.7, rcs-5.7, then cvs-1.5.

View File

@ -50,16 +50,16 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
# Where to install the executables.
bindir = $(exec_prefix)/bin
bindir = @bindir@
# Where to put the system-wide .cvsrc file
libdir = $(prefix)/lib
libdir = @libdir@
# Where to put the Info files
infodir = $(prefix)/info
infodir = @infodir@
# Where to put the manual pages.
mandir = $(prefix)/man
mandir = @mandir@
#### End of system configuration section. ####

View File

@ -1,5 +1,24 @@
Changes since 1.10:
* The new "cvs version" command gives a short version message. If
the repository is remote, both the client and server versions are
reported.
* "cvs admin -t" now works correctly in client/server mode.
* The "cvs history" command output format has changed -- the date
now includes the year and is given is ISO 8601 format (yyyy-mm-dd).
Also, the new LogHistory option in CVSROOT/config can be used to
control what information gets recorded in the log file and code has
been added to record file removals.
* The buggy PreservePermissions code has been disabled.
* Anonymous read-only access can now be done without requiring a
password. On the server side, simply give that user (presumably
`anonymous') an empty password in the CVSROOT/passwd file, and then
any received password will authenticate successfully.
* There is a new access method :fork: which is similar to :local:
except that it is implemented via the CVS remote protocol, and thus
has a somewhat different set of quirks and bugs.

View File

@ -97,9 +97,12 @@ versions of CVS?
On the web, http://www.loria.fr/~molli/cvs-index.html.
The mailing list for CVS is info-cvs@prep.ai.mit.edu. Send
See also
http://www.cvshome.org
The mailing list for CVS is info-cvs@gnu.org. Send
subscription and removal requests for that list to
info-cvs-request@prep.ai.mit.edu.
info-cvs-request@gnu.org.
The newsgroup for CVS (and other configuration management systems) is
comp.software.config-mgmt. There is not yet a CVS-specific newsgroup,

View File

@ -8,6 +8,8 @@ pathname of a shell which handles normal shell functions:
$ make SHELL=/bin/sh5 check
Also note that you must be logged in as a regular user, not root.
WARNING: This test can take quite a while to run, esp. if your
disks are slow or over-loaded.
@ -16,13 +18,22 @@ If for some reason you want them to work in a different directory, you
can set the TESTDIR environment variable to the desired location
before running them.
You will probably need GNU expr, which is part of the GNU sh-utils
package. This is just for running the tests; CVS itself doesn't
require expr.
With CVS 1.10 people also had trouble with the Solaris sort program
not behaving the way that the testsuite expects (with Solaris, lines
starting with tabs sort before blank lines).
The tests use a number of tools (awk, expr, id, tr, etc.) that are not
required for running CVS itself. In most cases, the standard vendor-
supplied versions of these tools work just fine, but there are some
exceptions -- expr in particular is heavily used and many vendor
versions are deficient in one way or another. Note that some vendors
provide multiple versions of tools (typically an ancient, traditional
version and a new, standards-conforming version), so you may already
have a usable version even if the default version isn't. If you don't
have a suitable tool, you can probably get one from the GNU Project (see
http://www.gnu.org). expr and id are both part of the GNU shellutils
package, tr is part of the GNU textutils package, and awk is part of the
GNU gawk package. The test script tries to verify that the tools exist
and are usable; if not, it tries to find the GNU versions and use them
instead. If it can't find the GNU versions either, it will print an
error message and, depending on the severity of the deficiency, it may
exit.
If there is some unexpected output, that is a failure which can be
somewhat hard to track down. Finding out which test is producing the

View File

@ -515,11 +515,6 @@ merges from one branch to the other happen automatically (for example,
the case in which the branches have not diverged). This might be a
legitimate question to ask even quite aside from multisite features.
One additional random tidbit is to note that Eric Raymond has some
interest in this sort of thing. The item "Cooperative distributed
freeware development" on http://www.ccil.org/~esr/ has a very brief
introduction to what he is thinking about.
187. Might want to separate out usage error messages and help
messages. The problem now is that if you specify an invalid option,
for example, the error message is lost among all the help text. In

View File

@ -43,3 +43,15 @@
/* Define if the diff library should use setmode for binary files.
FIXME: Why two different macros for setmode? */
#undef HAVE_SETMODE
/* Define if you have the crypt function. */
#undef HAVE_CRYPT
/* Define if you have the getspnam function. */
#undef HAVE_GETSPNAM
/* Define to force lib/regex.c to use malloc instead of alloca. */
#undef REGEX_MALLOC
/* Define to force lib/regex.c to define re_comp et al. */
#undef _REGEX_RE_COMP

View File

@ -16,12 +16,18 @@
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define if your system has a working fnmatch function. */
#undef HAVE_FNMATCH
/* Define if you support file names longer than 14 characters. */
#undef HAVE_LONG_FILE_NAMES
/* Define if your struct stat has st_blksize. */
#undef HAVE_ST_BLKSIZE
/* Define if your struct stat has st_rdev. */
#undef HAVE_ST_RDEV
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
@ -94,9 +100,6 @@
/* Define if you have the connect function. */
#undef HAVE_CONNECT
/* Define if this system supports chown(), link(), and friends. */
#undef PRESERVE_PERMISSIONS_SUPPORT
/* Define if you have memchr (always for CVS). */
#undef HAVE_MEMCHR
@ -117,6 +120,18 @@
/* Define if you have the crypt function. */
#undef HAVE_CRYPT
/* Define if you have the getspnam function. */
#undef HAVE_GETSPNAM
/* Define to force lib/regex.c to use malloc instead of alloca. */
#undef REGEX_MALLOC
/* Define to force lib/regex.c to define re_comp et al. */
#undef _REGEX_RE_COMP
/* Define if you have the dup2 function. */
#undef HAVE_DUP2
/* Define if you have the fchdir function. */
#undef HAVE_FCHDIR
@ -135,8 +150,8 @@
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
/* Define if you have the getspnam function. */
#undef HAVE_GETSPNAM
/* Define if you have the getpassphrase function. */
#undef HAVE_GETPASSPHRASE
/* Define if you have the initgroups function. */
#undef HAVE_INITGROUPS
@ -144,6 +159,15 @@
/* Define if you have the krb_get_err_text function. */
#undef HAVE_KRB_GET_ERR_TEXT
/* Define if you have the memmove function. */
#undef HAVE_MEMMOVE
/* Define if you have the mkdir function. */
#undef HAVE_MKDIR
/* Define if you have the mknod function. */
#undef HAVE_MKNOD
/* Define if you have the mktemp function. */
#undef HAVE_MKTEMP
@ -153,6 +177,9 @@
/* Define if you have the readlink function. */
#undef HAVE_READLINK
/* Define if you have the rename function. */
#undef HAVE_RENAME
/* Define if you have the sigaction function. */
#undef HAVE_SIGACTION
@ -168,6 +195,15 @@
/* Define if you have the sigvec function. */
#undef HAVE_SIGVEC
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
/* Define if you have the strstr function. */
#undef HAVE_STRSTR
/* Define if you have the strtoul function. */
#undef HAVE_STRTOUL
/* Define if you have the tempnam function. */
#undef HAVE_TEMPNAM
@ -177,12 +213,18 @@
/* Define if you have the tzset function. */
#undef HAVE_TZSET
/* Define if you have the valloc function. */
#undef HAVE_VALLOC
/* Define if you have the vprintf function. */
#undef HAVE_VPRINTF
/* Define if you have the wait3 function. */
#undef HAVE_WAIT3
/* Define if you have the waitpid function. */
#undef HAVE_WAITPID
/* Define if you have the <direct.h> header file. */
#undef HAVE_DIRECT_H
@ -207,6 +249,9 @@
/* Define if you have the <io.h> header file. */
#undef HAVE_IO_H
/* Define if you have the <krb5.h> header file. */
#undef HAVE_KRB5_H
/* Define if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
@ -255,23 +300,5 @@
/* Define if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
/* Define if you have the crypt library (-lcrypt). */
#undef HAVE_LIBCRYPT
/* Define if you have the gen library (-lgen). */
#undef HAVE_LIBGEN
/* Define if you have the inet library (-linet). */
#undef HAVE_LIBINET
/* Define if you have the nsl library (-lnsl). */
#undef HAVE_LIBNSL
/* Define if you have the nsl_s library (-lnsl_s). */
#undef HAVE_LIBNSL_S
/* Define if you have the sec library (-lsec). */
#undef HAVE_LIBSEC
/* Define if you have the socket library (-lsocket). */
#undef HAVE_LIBSOCKET

2598
contrib/cvs/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,42 +1,15 @@
dnl configure.in for cvs
AC_INIT(src/cvs.h)
dnl
AC_PREREQ(2.4)dnl Required Autoconf version.
dnl Do not use autoconf 2.12; it produces a configure script which produces
dnl a "internal 2K buffer" error on HPUX when run with /bin/sh.
dnl autoconf 2.10 seems like a good choice.
dnl
dnl It is possible that we should just change the above required version
dnl to 2.10; it seems like everyone is using 2.10 anyway, and there is
dnl at least some sentiment that we should be using a version which has
dnl --bindir (and correspondingly, using @bindir@ and friends in our
dnl Makefile.in files. Rumor has it that autoconf 2.7
dnl introduced --bindir but the point is that 2.10 has it.
AC_PREREQ(2.13)
AC_PREFIX_PROGRAM(cvs)
AC_CONFIG_HEADER(config.h src/options.h)
AC_PROG_AWK
AC_PROG_CC
AC_AIX
AC_MINIX
AC_ISC_POSIX
if test "$ISC" = yes; then
CFLAGS="$CFLAGS -D_SYSV3"
LIBS="-lcrypt $LIBS"
fi
AC_PREFIX_PROGRAM(cvs)
dnl FIXME: AC_C_CROSS is considered obsolete by autoconf 2.12, and is
dnl pretty ugly to start with. But it isn't obvious to me how we should
dnl be handling the uses of cross_compiling below.
AC_C_CROSS
AC_C_CONST
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_PROG_YACC
AC_PROG_MAKE_SET
AC_PATH_PROG(perl_path, perl, no)
AC_PATH_PROG(csh_path, csh, no)
@ -48,23 +21,35 @@ if test X"$ac_cv_sys_interpreter" != X"yes" ; then
AC_MSG_WARN($ac_msg)
fi
AC_AIX
AC_MINIX
AC_ISC_POSIX
if test "$ISC" = yes; then
CFLAGS="$CFLAGS -D_SYSV3"
LIBS="-lcrypt $LIBS"
fi
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(errno.h unistd.h string.h memory.h utime.h fcntl.h ndbm.h \
limits.h sys/file.h \
sys/param.h sys/select.h sys/time.h sys/timeb.h \
io.h direct.h sys/bsdtypes.h sys/resource.h)
AC_HEADER_SYS_WAIT
AC_HEADER_STAT
AC_HEADER_TIME
AC_HEADER_DIRENT
AC_TYPE_SIGNAL
AC_C_CONST
AC_TYPE_UID_T
AC_TYPE_MODE_T
AC_TYPE_SIZE_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_TYPE_SIGNAL
AC_STRUCT_ST_BLKSIZE
AC_STRUCT_ST_RDEV
AC_REPLACE_FUNCS(mkdir rename strstr dup2 strerror valloc waitpid memmove strtoul)
AC_CHECK_FUNCS(fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3)
AC_CHECK_FUNCS(fchmod fsync ftime mktemp putenv vprintf ftruncate timezone getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam tzset readlink wait3 mknod getpassphrase)
dnl
dnl The CVS coding standard (as specified in HACKING) is that if it exists
@ -74,6 +59,12 @@ dnl
AC_DEFINE(HAVE_STRCHR)
AC_DEFINE(HAVE_MEMCHR)
dnl
dnl Force lib/regex.c to use malloc instead of messing around with alloca
dnl and define the old re_comp routines that we use.
dnl
AC_DEFINE(REGEX_MALLOC)
AC_DEFINE(_REGEX_RE_COMP)
dnl
dnl AC_FUNC_VFORK is rather baroque. It seems to be rather more picky
dnl than, say, the Single Unix Specification (version 2), which simplifies
@ -96,77 +87,21 @@ dnl
dnl We used to try to determine whether shadow passwords were actually in
dnl use or not, but the code has been changed to work right reguardless,
dnl so we can go back to a simple check.
AC_CHECK_LIB(sec, getspnam)
AC_CHECK_FUNCS(getspnam)
AC_SEARCH_LIBS(getspnam, sec gen, AC_DEFINE(HAVE_GETSPNAM))
dnl We always use CVS's regular expression matcher.
dnl This is because:
dnl (1) If memory serves, the syntax of the regular expressions
dnl handled by re_exec is not consistent from system to system, which
dnl is a Bad Thing because CVS passes this syntax out to the user.
dnl We might have better luck with the POSIX interface, if we really
dnl want to look for a system-supplied matcher.
dnl (2) It is necessary to make _sure_ that we get a regex.h and regex.c
dnl that match each other. In particular, rx and the CVS/emacs
dnl regex.c have a different "struct re_pattern_buffer" and so using
dnl the system regex.h and our regex.c, or vice versa, will tend to
dnl cause a core dump.
dnl (3) Just as a random data point, CVS uses re_exec (a BSD interface);
dnl libdiff uses re_compile_pattern (a GNU interface, I think). Diff
dnl should probably be fixed to have the caller (CVS) supply the regexp
dnl matching.
dnl
dnl AC_CHECK_FUNC(re_exec, :, LIBOBJS="$LIBOBJS regex.o")
AC_FUNC_UTIME_NULL
AC_SYS_LONG_FILE_NAMES
AC_MSG_CHECKING([for working fnmatch function])
AC_CACHE_VAL(ccvs_cv_sys_working_fnmatch,
[AC_TRY_RUN([
#include <fnmatch.h>
int
main ()
{
exit ((fnmatch ("a", "a", FNM_PATHNAME) == 0
&& fnmatch ("a", "b", FNM_PATHNAME) == FNM_NOMATCH)
? 0 : 1);
}],
ccvs_cv_sys_working_fnmatch=yes,
ccvs_cv_sys_working_fnmatch=no,
ccvs_cv_sys_working_fnmatch=no)])
if test $ccvs_cv_sys_working_fnmatch = no; then
AC_FUNC_FNMATCH
if test "$ac_cv_func_fnmatch_works" = no; then
LIBOBJS="$LIBOBJS fnmatch.o"
fi
AC_MSG_RESULT($ccvs_cv_sys_working_fnmatch)
# 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
# only looks in /etc/hosts), so we only look for -lsocket if we need
# it.
AC_CHECK_FUNC(connect, :,
[case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl_s, printf) ;;
esac
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl, printf) ;;
esac
case "$LIBS" in
*-lsocket*) ;;
*) AC_CHECK_LIB(socket, connect) ;;
esac
case "$LIBS" in
*-linet*) ;;
*) AC_CHECK_LIB(inet, connect) ;;
esac
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
dnl has been cached.
if test "$ac_cv_lib_socket_connect" = "yes" || test "$ac_cv_lib_inet_connect" = "yes"; then
ac_cv_func_connect=yes
AC_DEFINE(HAVE_CONNECT)
fi])
# Try to find connect and gethostbyname.
AC_CHECK_LIB(nsl, main,
AC_SEARCH_LIBS(connect, xnet socket inet, AC_DEFINE(HAVE_CONNECT),, -lnsl),
AC_SEARCH_LIBS(connect, xnet socket inet, AC_DEFINE(HAVE_CONNECT)))
AC_SEARCH_LIBS(gethostbyname, netinet nsl)
dnl
dnl set $(KRB4) from --with-krb4=value -- WITH_KRB4
@ -314,7 +249,7 @@ AC_ARG_ENABLE(client,
[if test "$enable_client" = yes; then
AC_DEFINE(CLIENT_SUPPORT)
fi],
[if test "$ac_cv_func_connect" = yes; then
[if test "$ac_cv_search_connect" != no; then
AC_DEFINE(CLIENT_SUPPORT)
fi])
AC_ARG_ENABLE(server,
@ -323,34 +258,24 @@ AC_ARG_ENABLE(server,
[if test "$enable_server" = yes; then
AC_DEFINE(SERVER_SUPPORT)
fi],
[if test "$ac_cv_func_connect" = yes; then
[if test "$ac_cv_search_connect" != no; then
AC_DEFINE(SERVER_SUPPORT)
enable_server=yes
fi])
### The auth server needs to be able to check passwords against passwd
### file entries, so we only #define AUTH_SERVER_SUPPORT if we can
### find the crypt function.
###
### We used to test for crypt in libc first, and only add -lcrypt if
### we couldn't find it, but that interacts badly with the cache
### variables, the 'unset' command isn't portable, and I'm not sure
### there's any harm in just testing for -lcrypt first.
dnl The auth server needs to be able to check passwords against passwd
dnl file entries, so we only #define AUTH_SERVER_SUPPORT if we can
dnl find the crypt function.
if test "$enable_server" = yes; then
AC_CHECK_LIB(crypt, crypt)
AC_CHECK_FUNCS(crypt)
if test "$ac_cv_func_crypt" = yes; then
AC_DEFINE(AUTH_SERVER_SUPPORT)
fi
AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT) AC_DEFINE(AUTH_SERVER_SUPPORT))
fi # enable_server
dnl For the moment we will assume that all systems which have
dnl the unixyness to run configure are unixy enough to do the
dnl PreservePermissions stuff. I have this sinking feeling that
dnl things won't be that simple, before long.
AC_DEFINE(PRESERVE_PERMISSIONS_SUPPORT)
dnl AC_DEFINE(PRESERVE_PERMISSIONS_SUPPORT)
dnl On cygwin32, we configure like a Unix system, but we use the
dnl Windows support code in lib/fncase.c to handle the case

View File

@ -1,3 +1,20 @@
2000-09-07 Larry Jones <larry.jones@sdrc.com>
* Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
from autoconf.
2000-02-25 Larry Jones <larry.jones@sdr.com>
* log.pl: Get committer from command line instead of getlogin
so that client/server works correctly.
* loc_accum.pl: Ditto.
2000-01-24 K.J. Paradise <kj@sourcegear.com>
* sccs2rcs.csh: fixed a y2k bug. This was submitted
by Ceri Davies <ceri_davies@isdcorp.com>, and looks
okay to me.
1999-01-19 Graham Stoney <greyham@research.canon.com.au>
* log.pl: The author commited the canonical perl "localtime" Y2K

View File

@ -22,13 +22,13 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
# Where to install the executables.
bindir = $(exec_prefix)/bin
bindir = @bindir@
# Where to put the system-wide .cvsrc file
libdir = $(prefix)/lib
libdir = @libdir@
# Where to put the manual pages.
mandir = $(prefix)/man
mandir = @mandir@
# where to find command interpreters
perl_path = @perl_path@

View File

@ -6,9 +6,10 @@
# XXX -- I HATE Perl! This *will* be re-written in shell/awk/sed soon!
#
# Usage: log.pl [[-m user] ...] [-s] -f logfile 'dirname file ...'
# Usage: log.pl [-u user] [[-m mailto] ...] [-s] -f logfile 'dirname file ...'
#
# -m user - for each user to receive cvs log reports
# -u user - $USER passed from loginfo
# -m mailto - for each user to receive cvs log reports
# (multiple -m's permitted)
# -s - to prevent "cvs status -v" messages
# -f logfile - for the logfile to append to (mandatory,
@ -66,6 +67,8 @@ while (@ARGV) {
if ($arg eq '-m') {
$users = "$users " . shift @ARGV;
} elsif ($arg eq '-u') {
$login = shift @ARGV;
} elsif ($arg eq '-f') {
($logfile) && die "Too many '-f' args";
$logfile = shift @ARGV;
@ -95,7 +98,9 @@ $year += 1900;
# get a login name for the guy doing the commit....
#
$login = getlogin || (getpwuid($<))[0] || "nobody";
if ($login eq '') {
$login = getlogin || (getpwuid($<))[0] || "nobody";
}
# open log file for appending
#

View File

@ -13,7 +13,7 @@
#
# hacked greatly by Greg A. Woods <woods@planix.com>
# Usage: log_accum.pl [-d] [-s] [-M module] [[-m mailto] ...] [[-R replyto] ...] [-f logfile]
# Usage: log_accum.pl [-d] [-s] [-w] [-M module] [-u user] [[-m mailto] ...] [[-R replyto] ...] [-f logfile]
# -d - turn on debugging
# -m mailto - send mail to "mailto" (multiple)
# -R replyto - set the "Reply-To:" to "replyto" (multiple)
@ -21,6 +21,7 @@
# -f logfile - write commit messages to logfile too
# -s - *don't* run "cvs status -v" for each file
# -w - show working directory with log message
# -u user - $USER passed from loginfo
#
# Configurable options
@ -251,7 +252,6 @@ sub write_commitlog {
$debug = 0;
$id = getpgrp(); # note, you *must* use a shell which does setpgrp()
$state = $STATE_NONE;
$login = getlogin || (getpwuid($<))[0] || "nobody";
chop($hostname = `hostname`);
chop($domainname = `domainname`);
if ($domainname !~ '^\..*') {
@ -285,6 +285,8 @@ while (@ARGV) {
}
} elsif ($arg eq '-M') {
$modulename = shift @ARGV;
} elsif ($arg eq '-u') {
$login = shift @ARGV;
} elsif ($arg eq '-s') {
$do_status = 0;
} elsif ($arg eq '-w') {
@ -298,6 +300,9 @@ while (@ARGV) {
@files = split(/ /, $arg);
}
}
if ($login eq '') {
$login = getlogin || (getpwuid($<))[0] || "nobody";
}
($mailto) || die("No mail recipient specified (use -m)\n");
if ($replyto eq '') {
$replyto = $login;

View File

@ -177,6 +177,11 @@ foreach sfile (SCCS/s.*)
if ($status != 0) goto ERROR
# get file into current dir and get stats
set year = `echo $date | cut -c3-4`
if ($year < 70) then
# Y2K Bug, change century to 20
set date = `echo $date | sed -e s/19/20/`
endif
set date = `sccs prs -r$rev $file | grep "^D " | awk '{printf("19%s %s", $3, $4); exit}'`
set author = `sccs prs -r$rev $file | grep "^D " | awk '{print $5; exit}'`
echo ""

View File

@ -1,3 +1,33 @@
2000-08-03 Larry Jones <larry.jones@sdrc.com>
* diff3.c (read_diff): Use cvs_temp_name () instead of tmpnam () so
there's at least a chance of getting the file in the correct tmp dir.
2000-07-10 Larry Jones <larry.jones@sdrc.com>
* util.c (printf_output): Fix type clashes.
2000-06-15 Larry Jones <larry.jones@sdrc.com>
* diff3.c (diff3_run, make_3way_diff): Plug memory leaks.
1999-12-29 Jim Kingdon <http://developer.redhat.com/>
* diff.c (compare_files): Use explicit braces with if-if-else, per
GNU coding standards and gcc -Wall.
1999-11-23 Larry Jones <larry.jones@sdrc.com>
* diff3.c: Explicitly initialize zero_diff3 to placate neurotic
compilers that gripe about implicitly initialized const variables.
Reported by Eric Veum <sysv@yahoo.com>.
1999-09-15 Larry Jones <larry.jones@sdrc.com>
* diff.c (diff_run): Move the setjmp call before the options
processing since option errors can call fatal which in turn
calls longjmp.
1999-05-06 Jim Kingdon <http://www.cyclic.com>
* Makefile.in (DISTFILES): Remove libdiff.mak.

View File

@ -247,11 +247,21 @@ diff_run (argc, argv, out, callbacks_arg)
/* Do our initializations. */
initialize_main (&argc, &argv);
/* Decode the options. */
optind_old = optind;
optind = 0;
/* Set the jump buffer, so that diff may abort execution without
terminating the process. */
val = setjmp (diff_abort_buf);
if (val != 0)
{
optind = optind_old;
if (opened_file)
fclose (outfile);
return val;
}
/* Decode the options. */
while ((c = getopt_long (argc, argv,
"0123456789abBcC:dD:efF:hHiI:lL:nNpPqrsS:tTuU:vwW:x:X:y",
longopts, 0)) != EOF)
@ -686,17 +696,6 @@ diff_run (argc, argv, out, callbacks_arg)
}
}
/* Set the jump buffer, so that diff may abort execution without
terminating the process. */
val = setjmp (diff_abort_buf);
if (val != 0)
{
optind = optind_old;
if (opened_file)
fclose (outfile);
return val;
}
val = compare_files (0, argv[optind], 0, argv[optind + 1], 0);
/* Print any messages that were saved up for last. */
@ -1147,13 +1146,15 @@ compare_files (dir0, name0, dir1, name1, depth)
failed = 1;
}
if (inf[1].desc == -2)
if (same_files)
inf[1].desc = inf[0].desc;
else if ((inf[1].desc = open (inf[1].name, O_RDONLY, 0)) < 0)
{
perror_with_name (inf[1].name);
failed = 1;
}
{
if (same_files)
inf[1].desc = inf[0].desc;
else if ((inf[1].desc = open (inf[1].name, O_RDONLY, 0)) < 0)
{
perror_with_name (inf[1].name);
failed = 1;
}
}
#if HAVE_SETMODE
if (binary_I_O)

View File

@ -41,6 +41,8 @@ void printf_output PARAMS((char const *, ...))
;
void flush_output PARAMS((void));
char * cvs_temp_name PARAMS((void));
/*
* Internal data structures and macros for the diff3 program; includes
* data structures for both diff3 diffs and normal diffs.
@ -475,8 +477,6 @@ diff3_run (argc, argv, out, callbacks_arg)
free(content0);
free(content1);
free_diff_blocks(thread0);
free_diff_blocks(thread1);
free_diff3_blocks(diff3);
if (! callbacks || ! callbacks->write_output)
@ -676,7 +676,7 @@ make_3way_diff (thread0, thread1)
struct diff3_block const *last_diff3;
static struct diff3_block const zero_diff3;
static struct diff3_block const zero_diff3 = { 0 };
/* Initialization */
result = 0;
@ -765,6 +765,8 @@ make_3way_diff (thread0, thread1)
tmpblock = using_to_diff3_block (using, last_using,
base_water_thread, high_water_thread,
last_diff3);
free_diff_blocks(using[0]);
free_diff_blocks(using[1]);
if (!tmpblock)
diff3_fatal ("internal error: screwup in format of diff blocks");
@ -1274,7 +1276,7 @@ read_diff (filea, fileb, output_placement)
*ap++ = fileb;
*ap = 0;
diffout = tmpnam(NULL);
diffout = cvs_temp_name ();
outfile_hold = outfile;
callbacks_hold = callbacks;

View File

@ -366,7 +366,7 @@ printf_output (format, va_alist)
char *str;
int num;
int ch;
unsigned char buf[100];
char buf[100];
while ((q = strchr (p, '%')) != NULL)
{

View File

@ -1,3 +1,193 @@
2000-09-07 Larry Jones <larry.jones@sdrc.com>
* Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
from autoconf.
2000-08-21 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (Removing directories, export): Note that export always
prunes directories and remove references to the non-existent -P flag.
2000-07-28 Larry Jones <larry.jones@sdrc.com>
* cvsclient.texi (Requests): Ensure that all rootless requests say
that they're rootless.
2000-07-12 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (Module program options): Remove note that commit and
update programs only working locally; they've worked client/server
for quite some time.
2000-07-10 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (Invoking CVS): Document new version command.
* cvsclient.texi (Requests): Document new version request.
2000-07-06 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (admin options): Remove note about -t not working
in client/server.
2000-04-03 Pavel Roskin <pavel_roskin@geocities.com>
* cvs.texinfo (Telling CVS to notify you): Remove backslashes
before quotes.
2000-05-24 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (From files): Clean up @var{wdir}/@var{rdir} vs.
@var{dir} usage.
2000-05-19 Larry Jones <larry.jones@sdrc.com>
* cvsclient.texi (Requests): Note that Global_option is now
valid without Root.
2000-04-17 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (Variables): Clarify what USER means in pserver.
2000-03-08 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (Connection): Add note about inetd rate limit.
(ErrorMessages): Add root home directory permission messages.
2000-02-12 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo: Clean up text/formatting of previous change.
2000-02-21 K.J. Paradise <kj@sourcegear.com>
* cvs.texinfo : Adding John Cavanaugh's patch to allow
the history file to log actions based on the CVSROOT/config
file. (To limit which cvs actions actually make it into the
history file)
2000-02-17 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo: Remove references to PreservePermissions.
* cvs.texinfo (history options): Note default report type.
2000-01-18 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (Global options): Document compression levels.
2000-01-18 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo: Minor editorial changes from Ken Foskey
<waratah@zip.com.au>.
2000-01-11 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo: Add index entries for "Compression" and "Gzip".
Correct typography in many index entries (English phrases should
have initial caps, subcommands/files/etc. should be as-is).
2000-01-10 Karl Fogel <kfogel@red-bean.com>
* cvs.texinfo (loginfo): correctly describe CVSROOT/loginfo's
%-expansion behavior. Thanks to Karl Heinz Marbaise
<kama@hippo.fido.de> for noticing the error.
2000-01-07 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo (Password authentication server): Use -f in example
inetd.conf line.
(Connection): Add advice about using shell script or env to avoid
problems with inetd setting HOME in the server's environment.
(various): Use @file for inetd.conf.
2000-01-02 John P Cavanaugh <cavanaug@sr.hp.com>
* cvs.texinfo: document new -C option to update, now that it works
both remotely and locally.
(Re-applied by Karl Fogel <kfogel@red-bean.com>.)
1999-12-11 Karl Fogel <kfogel@red-bean.com>
* Revert previous change -- it doesn't work remotely yet.
1999-12-10 John P Cavanaugh <cavanaug@sr.hp.com>
* cvs.texinfo: document new -C option to update.
(Applied by Karl Fogel <kfogel@red-bean.com>.)
1999-11-20 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo(history options): Document -f, -n, and -z.
1999-11-09 Jim Kingdon <http://developer.redhat.com/>
* cvsclient.texi (Requests): Document the arguments to "log", now
that I've changed log.c to be more specific in terms of what it
will send.
1999-11-05 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo: Revert Karl's change once again since the code is now
fixed. Add "Variables" and "User variables" to index.
1999-11-04 Karl Fogel <kfogel@red-bean.com>
* log.c (log_usage): Revert Jim Kingdon's reversion of my change
of 1999-11-03. Allowing a space between option and argument
results in lossage; here is a reproduction recipe: run this from
the top of a remote copy of the cvs source tree
cvs log -d '>1999-03-01' > log-out.with-space
and then run this (note there's no space after -d now):
cvs log -d'>1999-03-01' > log-out.no-space
The resulting files differ; furthermore, a glance at the output of
cvs shows that the first command failed to recurse into
subdirectories. Until this misbehavior can be fixed in the source
code, the documentation should reflect the true state of affairs:
if one simply omits the space, everything works fine.
1999-11-04 Jim Kingdon <http://developer.redhat.com/>
* cvs.texinfo (log options): Revert Karl's change regarding -d and
-s. A space is allowed (see sanity.sh for example).
* cvs.texinfo (Password authentication server): The name of the
file is "passwd" not "password".
* cvsclient.texi (Top): Add @dircategory and @direntry.
1999-11-04 Karl Fogel <kfogel@red-bean.com>
* cvs.texinfo (Password authentication server, Password
authentication client): Rewritten to accommodate the [new]
possibility of empty passwords.
1999-11-03 Karl Fogel <kfogel@red-bean.com>
* cvs.texinfo (Invoking CVS): correct documentation for -d and -s
options (as did elsewhere, earlier today).
1999-11-03 Karl Fogel <kfogel@red-bean.com>
* cvs.texinfo (Setting a watch): describe `watch off' behavior
more accurately.
1999-11-03 Karl Fogel <kfogel@red-bean.com>
* cvs.texinfo (log options): correct documentation for -d and -s
options. There can be no space between these options and their
arguments.
Also, make sure all @sc{cvs} codes refer to "cvs" in lower case;
this avoids makeinfo warnings. And use @code for the CVSEDITOR
environment variable, not @sc.
1999-09-24 Larry Jones <larry.jones@sdrc.com>
* cvs.texinfo: Misc. formatting cleanups.
1999-07-16 Tom Tromey <tromey@cygnus.com>
* cvs.texinfo (admin): Mention admin -k exception. Add cvsadmin

View File

@ -21,7 +21,7 @@ VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
infodir = $(prefix)/info
infodir = @infodir@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,11 @@
@setfilename cvsclient.info
@include CVSvn.texi
@dircategory Programming
@direntry
* cvsclient: (cvsclient). The CVS client/server protocol.
@end direntry
@node Top
@top CVS Client/Server
@ -492,7 +497,7 @@ command line client (versions 1.5 through at least 1.9).
For the @samp{-d} option to the @code{log} request, servers should at
least support RFC 822/1123 format. Clients are encouraged to use this
format too (traditionally the command line CVS client has just passed
format too (the command line CVS client, version 1.10 and older, just passed
along the date format specified by the user, however).
The @code{Mod-time} response and @code{Checkin-time} request use RFC
@ -537,16 +542,19 @@ in use, connection, authentication, etc., are already taken care of.
The @code{Root} request must be sent only once, and it must be sent
before any requests other than @code{Valid-responses},
@code{valid-requests}, @code{UseUnchanged}, @code{Set} or @code{init}.
@code{valid-requests}, @code{UseUnchanged}, @code{Set},
@code{Global_option}, @code{init}, @code{noop}, or @code{version}.
@item Valid-responses @var{request-list} \n
Response expected: no.
Tell the server what responses the client will accept.
request-list is a space separated list of tokens.
The @code{Root} request need not have been previously sent.
@item valid-requests \n
Response expected: yes.
Ask the server to send back a @code{Valid-requests} response.
The @code{Root} request need not have been previously sent.
@item Directory @var{local-directory} \n
Additional data: @var{repository} \n. Response expected: no.
@ -859,6 +867,7 @@ must not contain @samp{/}.
Response expected: no. To specify the version of the protocol described
in this document, servers must support this request (although it need
not do anything) and clients must issue it.
The @code{Root} request need not have been previously sent.
@item Notify @var{filename} \n
Response expected: no.
@ -950,6 +959,7 @@ strings, no variations (such as combining of options) are allowed. For
graceful handling of @code{valid-requests}, it is probably better to
make new global options separate requests, rather than trying to add
them to this request.
The @code{Root} request need not have been previously sent.
@item Gzip-stream @var{level} \n
Response expected: no.
@ -1007,6 +1017,7 @@ connection between the initial authentication and the
@item Set @var{variable}=@var{value} \n
Response expected: no.
Set a user variable @var{variable} to @var{value}.
The @code{Root} request need not have been previously sent.
@item expand-modules \n
Response expected: yes. Expand the modules which are specified in the
@ -1064,7 +1075,6 @@ directory.
@itemx diff \n
@itemx tag \n
@itemx status \n
@itemx log \n
@itemx admin \n
@itemx history \n
@itemx watchers \n
@ -1078,6 +1088,56 @@ of the operation. No provision is made for any input from the user.
This means that @code{ci} must use a @code{-m} argument if it wants to
specify a log message.
@item log \n
Response expected: yes. Show information for past revisions. This uses
any previous @code{Directory}, @code{Entry}, or @code{Modified}
requests, if they have been sent. The last @code{Directory} sent
specifies the working directory at the time of the operation. Also uses
previous @code{Argument}'s of which the canonical forms are the
following (@sc{cvs} 1.10 and older clients sent what the user specified,
but clients are encouraged to use the canonical forms and other forms
are deprecated):
@table @code
@item -b, -h, -l, -N, -R, -t
These options go by themselves, one option per @code{Argument} request.
@item -d @var{date1}<@var{date2}
Select revisions between @var{date1} and @var{date2}. Either date
may be omitted in which case there is no date limit at that end of the
range (clients may specify dates such as 1 Jan 1970 or 1 Jan 2038 for
similar purposes but this is problematic as it makes assumptions about
what dates the server supports). Dates are in RFC822/1123 format. The
@samp{-d} is one @code{Argument} request and the date range is a second
one.
@item -d @var{date1}<=@var{date2}
Likewise but compare dates for equality.
@item -d @var{singledate}
Select the single, latest revision dated @var{singledate} or earlier.
To include several date ranges and/or singledates, repeat the @samp{-d}
option as many times as necessary.
@item -r@var{rev1}:@var{rev2}
@itemx -r@var{branch}
@itemx -r@var{branch}.
@itemx -r
Specify revisions (note that @var{rev1} or @var{rev2} can be omitted, or
can refer to branches). Send both the @samp{-r} and the revision
information in a single @code{Argument} request. To include several
revision selections, repeat the @samp{-r} option.
@item -s @var{state}
@itemx -w
@itemx -w@var{login}
Select on states or users. To include more than one state or user,
repeat the option. Send the @samp{-s} option as a separate argument
from the state being selected. Send the @samp{-w} option as part of the
same argument as the user being selected.
@end table
@item co \n
Response expected: yes. Get files from the repository. This uses any
previous @code{Argument}, @code{Directory}, @code{Entry}, or
@ -1111,8 +1171,8 @@ commands are module names, as described for @code{co}.
@item init @var{root-name} \n
Response expected: yes. If it doesn't already exist, create a @sc{cvs}
repository @var{root-name}. Note that @var{root-name} is a local
directory and @emph{not} a fully qualified @code{CVSROOT} variable. The
@code{Root} request need not have been previously sent.
directory and @emph{not} a fully qualified @code{CVSROOT} variable.
The @code{Root} request need not have been previously sent.
@item update \n
Response expected: yes. Actually do a @code{cvs update} command. This
@ -1245,6 +1305,7 @@ Response expected: yes. This request is a null command in the sense
that it doesn't do anything, but merely (as with any other requests
expecting a response) sends back any responses pertaining to pending
errors, pending @code{Notified} responses, etc.
The @code{Root} request need not have been previously sent.
@item update-patches \n
Response expected: yes.
@ -1277,6 +1338,11 @@ Response expected: yes.
Request that the server transmit mappings from filenames to keyword
expansion modes in @code{Wrapper-rcsOption} responses.
@item version \n
Response expected: yes.
Request that the server transmit its version message.
The @code{Root} request need not have been previously sent.
@item @var{other-request} @var{text} \n
Response expected: yes.
Any unrecognized request expects a response, and does not
@ -1934,8 +2000,8 @@ working directory, and the meaning of sending @code{Entries} without
A number of enhancements are possible. Also see the file @sc{todo} in
the @sc{cvs} source distribution, which has further ideas concerning
various aspects of @sc{cvs}, some of which impact the protocol.
Similarly, the @code{http://www.cyclic.com} site, in particular the
@cite{Development of CVS} page.
Similarly, the @code{http://www.cvshome.org} site, in particular the
@cite{Development} pages.
@itemize @bullet
@item

View File

@ -10,6 +10,7 @@
# This script is compatible with the BSD install script, but was written
# from scratch.
#
#
# set DOITPROG to echo to test this script

View File

@ -1,3 +1,46 @@
2000-07-10 Larry Jones <larry.jones@sdrc.com>
* savecwd.c: #include <sys/types.h> before <fcntl.h>.
2000-07-04 Karl Fogel <kfogel@red-bean.com>
* getline.h, getline.c (getstr): take new limit arg.
(GETLINE_NO_LIMIT): new #define.
(getline_safe): new function, takes limit arg and passes it on.
(getline): pass GETLINE_NO_LIMIT to getstr().
See related change of same date in ../src/ChangeLog.
2000-06-19 Larry Jones <larry.jones@sdrc.com>
* regex.c, regex.h: Version from emacs 20.7 to plug memory leaks
and avoid potential portability problems.
2000-03-22 Larry Jones <larry.jones@sdrc.com>
* getdate.y: Add logic to allow yyyy/mm/dd in addition to mm/dd/yy
(since that is the format CVS frequently uses).
* getdate.c: Regenerated.
2000-02-16 Jim Meyering <meyering@lucent.com>
* sighandle.c (SIG_inCrSect): New function.
2000-01-03 Larry Jones <larry.jones@sdrc.com>
* getdate.y (Convert): Add window to determine whether 2-digit dates
are 19xx (69-99) or 20xx (00-68).
(get_date): Fix y2k bug: initialize yyYear to tm_year + 1900,
not just tm_year.
* getdate.c: Regenerated.
1999-12-29 Jim Kingdon <http://developer.redhat.com/>
* Makefile.in: There was a comment here which referred to a long
comment in configure.in about regex.o (the configure.in comment
isn't there any more). Replace our comment with a conciser
version of the former configure.in comment.
1999-03-26 Jim Kingdon <http://www.cyclic.com>
* getopt.h: Don't declare the arguments to getopt.

View File

@ -52,7 +52,16 @@ SOURCES = \
HEADERS = getline.h getopt.h fnmatch.h regex.h system.h wait.h md5.h savecwd.h
# See long comment in ../configure.in concerning inclusion of regex.o.
# Always use CVS's regular expression matcher regex.o, because of
# variations in regular expression syntax - we want to be the same
# across systems and (probably) compared with old versions of CVS too.
#
# On a more mundane/detail level, having regex.h match regex.c can be
# an issue if we aren't careful.
#
# Also should look into unifying regular expression matching in CVS
# with the diff library (perhaps to have the caller, CVS, do the
# matching?)
OBJECTS = \
@LIBOBJS@ \
argmatch.o \

View File

@ -281,9 +281,15 @@ date : tUNUMBER '/' tUNUMBER {
yyDay = $3;
}
| tUNUMBER '/' tUNUMBER '/' tUNUMBER {
yyMonth = $1;
yyDay = $3;
yyYear = $5;
if ($1 >= 100) {
yyYear = $1;
yyMonth = $3;
yyDay = $5;
} else {
yyMonth = $1;
yyDay = $3;
yyYear = $5;
}
}
| tUNUMBER tSNUMBER tSNUMBER {
/* ISO 8601 format. yyyy-mm-dd. */
@ -643,7 +649,9 @@ Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
if (Year < 0)
Year = -Year;
if (Year < 100)
if (Year < 69)
Year += 2000;
else if (Year < 100)
Year += 1900;
DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
? 29 : 28;
@ -957,7 +965,7 @@ get_date(p, now)
}
tm = localtime(&nowtime);
yyYear = tm->tm_year;
yyYear = tm->tm_year + 1900;
yyMonth = tm->tm_mon + 1;
yyDay = tm->tm_mday;
yyTimezone = now->timezone;

View File

@ -22,6 +22,7 @@ General Public License for more details. */
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include "getline.h"
#if STDC_HEADERS
#include <stdlib.h>
@ -33,20 +34,25 @@ char *malloc (), *realloc ();
#define MIN_CHUNK 64
/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
+ OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
malloc (or NULL), pointing to *N characters of space. It is realloc'd
as necessary. Return the number of characters read (not including the
null terminator), or -1 on error or EOF. On a -1 return, the caller
should check feof(), if not then errno has been set to indicate
the error. */
+ OFFSET (and null-terminate it). If LIMIT is non-negative, then
read no more than LIMIT chars.
*LINEPTR is a pointer returned from malloc (or NULL), pointing to
*N characters of space. It is realloc'd as necessary.
Return the number of characters read (not including the null
terminator), or -1 on error or EOF. On a -1 return, the caller
should check feof(), if not then errno has been set to indicate the
error. */
int
getstr (lineptr, n, stream, terminator, offset)
getstr (lineptr, n, stream, terminator, offset, limit)
char **lineptr;
size_t *n;
FILE *stream;
char terminator;
int offset;
int limit;
{
int nchars_avail; /* Allocated but unused chars in *LINEPTR. */
char *read_pos; /* Where we're reading into *LINEPTR. */
@ -75,7 +81,19 @@ getstr (lineptr, n, stream, terminator, offset)
for (;;)
{
int save_errno;
register int c = getc (stream);
register int c;
if (limit == 0)
break;
else
{
c = getc (stream);
/* If limit is negative, then we shouldn't pay attention to
it, so decrement only if positive. */
if (limit > 0)
limit--;
}
save_errno = errno;
@ -141,5 +159,15 @@ getline (lineptr, n, stream)
size_t *n;
FILE *stream;
{
return getstr (lineptr, n, stream, '\n', 0);
return getstr (lineptr, n, stream, '\n', 0, GETLINE_NO_LIMIT);
}
int
getline_safe (lineptr, n, stream, limit)
char **lineptr;
size_t *n;
FILE *stream;
int limit;
{
return getstr (lineptr, n, stream, '\n', 0, limit);
}

View File

@ -9,10 +9,15 @@
#define __PROTO(args) ()
#endif /* GCC. */
#define GETLINE_NO_LIMIT -1
int
getline __PROTO ((char **_lineptr, size_t *_n, FILE *_stream));
int
getline_safe __PROTO ((char **_lineptr, size_t *_n, FILE *_stream,
int limit));
int
getstr __PROTO ((char **_lineptr, size_t *_n, FILE *_stream,
char _terminator, int _offset));
char _terminator, int _offset, int limit));
#endif /* _getline_h_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* Definitions for data structures and routines for the regular
expression library, version 0.12.
Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Copyright (C) 1985, 89, 90, 91, 92, 93, 95 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
@ -11,7 +11,12 @@
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. */
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA. */
#ifndef __REGEXP_LIBRARY_H__
#define __REGEXP_LIBRARY_H__
@ -19,7 +24,7 @@
/* POSIX says that <sys/types.h> must be included (by the caller) before
<regex.h>. */
#ifdef VMS
#if !defined (_POSIX_C_SOURCE) && !defined (_POSIX_SOURCE) && defined (VMS)
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
should be there. */
#include <stddef.h>
@ -126,11 +131,22 @@ typedef unsigned reg_syntax_t;
If not set, then an unmatched ) is invalid. */
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
/* If this bit is set, succeed as soon as we match the whole pattern,
without further backtracking. */
#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
/* This global variable defines the particular regexp syntax to use (for
some interfaces). When a regexp is compiled, the syntax used is
stored in the pattern buffer, so changing this does not affect
already-compiled regexps. */
extern reg_syntax_t re_syntax_options;
#ifdef emacs
/* In Emacs, this is the string or buffer in which we
are matching. It is used for looking up syntax properties. */
extern Lisp_Object re_match_object;
#endif
/* Define combinations of the above bits for the standard possibilities.
(The [[[ comments delimit what gets put into the Texinfo file, so
@ -271,6 +287,12 @@ typedef enum
compiled, the `re_nsub' field is available. All other fields are
private to the regex routines. */
#ifndef RE_TRANSLATE_TYPE
#define RE_TRANSLATE_TYPE char *
#define RE_TRANSLATE(TBL, C) ((TBL)[C])
#define RE_TRANSLATE_P(TBL) (TBL)
#endif
struct re_pattern_buffer
{
/* [[[begin pattern_buffer]]] */
@ -297,7 +319,7 @@ struct re_pattern_buffer
comparing them, or zero for no translation. The translation
is applied to a pattern when it is compiled and to a string
when it is matched. */
char *translate;
RE_TRANSLATE_TYPE translate;
/* Number of subexpressions found by the compiler. */
size_t re_nsub;
@ -336,15 +358,14 @@ struct re_pattern_buffer
/* If true, an anchor at a newline matches. */
unsigned newline_anchor : 1;
/* If true, multi-byte form in the `buffer' should be recognized as a
multibyte character. */
unsigned multibyte : 1;
/* [[[end pattern_buffer]]] */
};
typedef struct re_pattern_buffer regex_t;
/* search.c (search_buffer) in Emacs needs this one opcode value. It is
defined both in `regex.c' and here. */
#define RE_EXACTN_VALUE 1
/* Type for byte offsets within the string. POSIX mandates this. */
typedef int regoff_t;
@ -461,11 +482,12 @@ extern void re_set_registers
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
unsigned num_regs, regoff_t *starts, regoff_t *ends));
/* 4.2 bsd compatibility. System headers may declare the argument as
either "char *" (e.g. Cray unistd.h) or "const char *" (e.g. linux
regex.h), so don't prototype them here. */
extern char *re_comp ();
extern int re_exec ();
#ifdef _REGEX_RE_COMP
/* 4.2 bsd compatibility. */
/* CVS: don't use prototypes: they may conflict with system headers. */
extern char *re_comp _RE_ARGS (());
extern int re_exec _RE_ARGS (());
#endif
/* POSIX compatibility. */
extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));

View File

@ -13,6 +13,7 @@
#endif
#ifdef HAVE_FCNTL_H
# include <sys/types.h>
# include <fcntl.h>
#else
# include <sys/file.h>

View File

@ -383,6 +383,16 @@ void SIG_beginCrSect()
}
}
/*
* Return nonzero if currently in a critical section.
* Otherwise return zero.
*/
int SIG_inCrSect()
{
return SIG_crSectNest > 0;
}
/*
* The following ends a critical section.
*/

View File

@ -1,3 +1,37 @@
2000-09-07 Larry Jones <larry.jones@sdrc.com>
* Makefile.in: Use @bindir@, @libdir@, @infodir@, and @mandir@
from autoconf.
2000-05-03 Larry Jones <larry.jones@sdrc.com>
* cvs.1: Correct CVSEDITOR/VISUAL/EDITOR documentation.
Correct KJ's botched patch application.
2000-01-02 John P Cavanaugh <cavanaug@sr.hp.com>
* cvs.texinfo: document new -C option to update, now that it works
both remotely and locally.
(Re-applied by Karl Fogel <kfogel@red-bean.com>.)
1999-12-11 Karl Fogel <kfogel@red-bean.com>
* Revert previous change -- it doesn't work remotely yet.
1999-12-10 John P Cavanaugh <cavanaug@sr.hp.com>
* cvs.1: document new -C option to update.
(Applied by Karl Fogel <kfogel@red-bean.com>.)
1999-11-29 Larry Jones <larry.jones@sdrc.com>
* cvsbug.8: Change .TH from section 1 to section 8.
1999-11-10 Jim Kingdon <http://developer.redhat.com/>
* cvs.1: Don't document -H as a command option; it has been a
while since that worked.
1999-01-19 Vitaly V Fedrushkov <willy@snowyowl.csu.ac.ru>
* Makefile.in (INSTALL_DATA): Wrong manpage permissions fixed.

View File

@ -27,7 +27,7 @@ DISTFILES = .cvsignore ChangeLog Makefile.in $(MANFILES)
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
prefix = @prefix@
mandir = $(prefix)/man
mandir = @mandir@
man1dir = $(mandir)/man1
man5dir = $(mandir)/man5
man8dir = $(mandir)/man8

View File

@ -192,8 +192,10 @@ Use
.I editor
to enter revision log information.
Overrides the setting of the
.SM CVSEDITOR
and the
.SM CVSEDITOR\c
,
.SM VISUAL\c
, and
.SM EDITOR
environment variables.
.TP
@ -358,6 +360,11 @@ file; see
Incorporate a set of updates from off-site into the source repository,
as a ``vendor branch''. (Changes repository.)
.TP
.B init
Initialize a repository by adding the CVSROOT subdirectory and some default
control files. You must use this command or initialize the repository in
some other way before you can use it.
.TP
.B log
Display
log information.
@ -473,13 +480,6 @@ is available with these commands:
.BR checkout ", " export ", "
.BR rdiff ", " rtag ", and " update .
.TP
.B \-H
Help; describe the options available for this command. This is the
only option supported for
.I all
.B cvs
commands.
.TP
\fB\-k\fP \fIkflag\fP
Alter the default
processing of keywords.
@ -1684,7 +1684,7 @@ executes recursively through subdirectories; you can prevent this by
using the standard \fB\-l\fP option, or specify the recursion
explicitly by using \fB\-R\fP.
.TP
\fBupdate\fP [\fB\-Adf\|lPpQqR\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP|\fB\-D\fP \fIdate\fP] \fIfiles\|.\|.\|.\fP
\fBupdate\fP [\fB\-ACdf\|lPpQqR\fP] [\fB\-d\fP] [\fB\-r\fP \fItag\fP|\fB\-D\fP \fIdate\fP] \fIfiles\|.\|.\|.\fP
.I Requires:
repository, working directory.
.br
@ -1841,6 +1841,12 @@ Use
.` "\-I !"
to avoid ignoring any files at all.
.SP
Use the
.` "\-C"
option to overwrite locally modified files with clean copies from
the repository (the modified file is saved in
`\fB.#\fP\fIfile\fP\fB.\fP\fIrevision\fP', however).
.SP
The standard \fBcvs\fP command options \fB\-f\fP, \fB\-k\fP,
\fB\-l\fP, \fB\-P\fP, \fB\-p\fP, and \fB\-r\fP
are also available with \fBupdate\fP.
@ -2035,12 +2041,13 @@ and
Specifies the program to use for recording log messages during
.BR commit .
If not set, the
.SM VISUAL
and
.SM EDITOR
environment variable is used instead.
If
.SM EDITOR
is not set either, the default is
.BR /usr/ucb/vi .
environment variables are tried (in that order).
If neither is set, a system-dependent default editor (e.g.,
.BR vi )
is used.
.TP
.SM CVS_IGNORE_REMOTE_ROOT
If this variable is set then

View File

@ -18,7 +18,7 @@
.\"
.\" ---------------------------------------------------------------------------
.nh
.TH CVSBUG 1 xVERSIONx "February 1993"
.TH CVSBUG 8 xVERSIONx "February 1993"
.SH NAME
cvsbug \- send problem report (PR) about CVS to a central support site
.SH SYNOPSIS

View File

@ -4,6 +4,7 @@
# Created: 1993-05-16
# Last modified: 1994-03-25
# Public domain
#
errstatus=0

File diff suppressed because it is too large Load Diff

View File

@ -22,13 +22,13 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
# Where to install the executables.
bindir = $(exec_prefix)/bin
bindir = @bindir@
# Where to put the system-wide .cvsrc file
libdir = $(prefix)/lib
libdir = @libdir@
# Where to put the manual pages.
mandir = $(prefix)/man
mandir = @mandir@
# Use cp if you don't have install.
INSTALL = @INSTALL@

View File

@ -59,6 +59,7 @@ add (argc, argv)
/* Nonzero if we found a slash, and are thus adding files in a
subdirectory. */
int found_slash = 0;
size_t cvsroot_len;
if (argc == 1 || argc == -1)
usage (add_usage);
@ -92,6 +93,8 @@ add (argc, argv)
if (argc <= 0)
usage (add_usage);
cvsroot_len = strlen (CVSroot_directory);
/* First some sanity checks. I know that the CVS case is (sort of)
also handled by add_directory, but we need to check here so the
client won't get all confused in send_file_names. */
@ -157,7 +160,11 @@ add (argc, argv)
start_server ();
ign_setup ();
if (options) send_arg(options);
if (options)
{
send_arg (options);
free (options);
}
option_with_arg ("-m", message);
/* If !found_slash, refrain from sending "Directory", for
@ -219,6 +226,17 @@ add (argc, argv)
/* find the repository associated with our current dir */
repository = Name_Repository (NULL, update_dir);
/* don't add stuff to Emptydir */
if (strncmp (repository, CVSroot_directory, cvsroot_len) == 0
&& ISDIRSEP (repository[cvsroot_len])
&& strncmp (repository + cvsroot_len + 1,
CVSROOTADM,
sizeof CVSROOTADM - 1) == 0
&& ISDIRSEP (repository[cvsroot_len + sizeof CVSROOTADM])
&& strcmp (repository + cvsroot_len + sizeof CVSROOTADM + 1,
CVSNULLREPOS) == 0)
error (1, 0, "cannot add to %s", repository);
/* before we do anything else, see if we have any
per-directory tags */
ParseTag (&tag, &date, &nonbranch);
@ -227,7 +245,7 @@ add (argc, argv)
sprintf (rcsdir, "%s/%s", repository, p);
Create_Admin (p, argv[i], rcsdir, tag, date,
nonbranch, 0);
nonbranch, 0, 1);
if (found_slash)
send_a_repository ("", repository, update_dir);
@ -304,6 +322,17 @@ add (argc, argv)
/* Find the repository associated with our current dir. */
repository = Name_Repository (NULL, finfo.update_dir);
/* don't add stuff to Emptydir */
if (strncmp (repository, CVSroot_directory, cvsroot_len) == 0
&& ISDIRSEP (repository[cvsroot_len])
&& strncmp (repository + cvsroot_len + 1,
CVSROOTADM,
sizeof CVSROOTADM - 1) == 0
&& ISDIRSEP (repository[cvsroot_len + sizeof CVSROOTADM])
&& strcmp (repository + cvsroot_len + sizeof CVSROOTADM + 1,
CVSNULLREPOS) == 0)
error (1, 0, "cannot add to %s", repository);
entries = Entries_Open (0, NULL);
finfo.repository = repository;
@ -619,6 +648,8 @@ cannot resurrect %s; RCS file removed by second party", finfo.fullname);
if (message)
free (message);
if (options)
free (options);
return (err);
}
@ -769,10 +800,8 @@ add_directory (finfo)
#ifdef SERVER_SUPPORT
if (!server_active)
Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0);
#else
Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0);
#endif
Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0, 1);
if (tag)
free (tag);
if (date)

View File

@ -22,7 +22,45 @@ static int admin_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static const char *const admin_usage[] =
{
"Usage: %s %s rcs-options files...\n",
"Usage: %s %s [options] files...\n",
"\t-a users Append (comma-separated) user names to access list.\n",
"\t-A file Append another file's access list.\n",
"\t-b[rev] Set default branch (highest branch on trunk if omitted).\n",
"\t-c string Set comment leader.\n",
"\t-e[users] Remove (comma-separated) user names from access list\n",
"\t (all names if omitted).\n",
"\t-I Run interactively.\n",
"\t-k subst Set keyword substitution mode:\n",
"\t kv (Default) Substitue keyword and value.\n",
"\t kvl Substitue keyword, value, and locker (if any).\n",
"\t k Substitue keyword only.\n",
"\t o Preserve original string.\n",
"\t b Like o, but mark file as binary.\n",
"\t v Substitue value only.\n",
"\t-l[rev] Lock revision (latest revision on branch,\n",
"\t latest revision on trunk if omitted).\n",
"\t-L Set strict locking.\n",
"\t-m rev:msg Replace revision's log message.\n",
"\t-n tag[:[rev]] Tag branch or revision. If :rev is omitted,\n",
"\t delete the tag; if rev is omitted, tag the latest\n",
"\t revision on the default branch.\n",
"\t-N tag[:[rev]] Same as -n except override existing tag.\n",
"\t-o range Delete (outdate) specified range of revisions:\n",
"\t rev1::rev2 Between rev1 and rev2, excluding rev1 and rev2.\n",
"\t rev:: After rev on the same branch.\n",
"\t ::rev Before rev on the same branch.\n",
"\t rev Just rev.\n",
"\t rev1:rev2 Between rev1 and rev2, including rev1 and rev2.\n",
"\t rev: rev and following revisions on the same branch.\n",
"\t :rev rev and previous revisions on the same branch.\n",
"\t-q Run quietly.\n",
"\t-s state[:rev] Set revision state (latest revision on branch,\n",
"\t latest revision on trunk if omitted).\n",
"\t-t[file] Get descriptive text from file (stdin if omitted).\n",
"\t-t-string Set descriptive text.\n",
"\t-u[rev] Unlock the revision (latest revision on branch,\n",
"\t latest revision on trunk if omitted).\n",
"\t-U Unset strict locking.\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
@ -53,9 +91,7 @@ struct admin_data
/* Keyword substitution mode (-k), e.g. "-kb". */
char *kflag;
/* Description (-t). See sanity.sh for various moanings about
files and stdin and such. "" if -t specified without an
argument. It is "-t" followed by the argument. */
/* Description (-t). */
char *desc;
/* Interactive (-I). Problematic with client/server. */
@ -191,11 +227,6 @@ admin (argc, argv)
break;
case 'e':
if (optarg == NULL)
{
error (1, 0,
"removing entire access list not yet implemented");
}
arg_add (&admin_data, 'e', optarg);
break;
@ -287,13 +318,15 @@ admin (argc, argv)
error (0, 0, "duplicate 't' option");
goto usage_error;
}
if (optarg == NULL)
admin_data.desc = xstrdup ("-t");
if (optarg != NULL && optarg[0] == '-')
admin_data.desc = xstrdup (optarg + 1);
else
{
admin_data.desc = xmalloc (strlen (optarg) + 5);
strcpy (admin_data.desc, "-t");
strcat (admin_data.desc, optarg);
size_t bufsize = 0;
size_t len;
get_file (optarg, optarg, "r", &admin_data.desc,
&bufsize, &len);
}
break;
@ -417,7 +450,26 @@ admin (argc, argv)
if (admin_data.delete_revs != NULL)
send_arg (admin_data.delete_revs);
if (admin_data.desc != NULL)
send_arg (admin_data.desc);
{
char *p = admin_data.desc;
send_to_server ("Argument -t-", 0);
while (*p)
{
if (*p == '\n')
{
send_to_server ("\012Argumentx ", 0);
++p;
}
else
{
char *q = strchr (p, '\n');
if (q == NULL) q = p + strlen (p);
send_to_server (p, q - p);
p = q;
}
}
send_to_server ("\012", 1);
}
if (admin_data.quiet)
send_arg ("-q");
if (admin_data.kflag != NULL)
@ -598,20 +650,7 @@ admin_fileproc (callerdat, finfo)
if (admin_data->desc != NULL)
{
free (rcs->desc);
rcs->desc = NULL;
if (admin_data->desc[2] == '-')
rcs->desc = xstrdup (admin_data->desc + 3);
else
{
char *descfile = admin_data->desc + 2;
size_t bufsize = 0;
size_t len;
/* If -t specified with no argument, read from stdin. */
if (*descfile == '\0')
descfile = NULL;
get_file (descfile, descfile, "r", &rcs->desc, &bufsize, &len);
}
rcs->desc = xstrdup (admin_data->desc);
}
if (admin_data->kflag != NULL)
{
@ -642,6 +681,8 @@ admin_fileproc (callerdat, finfo)
if (arg[1] == 'a')
for (u = 0; u < argc; ++u)
RCS_addaccess (rcs, users[u]);
else if (argc == 0)
RCS_delaccess (rcs, NULL);
else
for (u = 0; u < argc; ++u)
RCS_delaccess (rcs, users[u]);
@ -748,20 +789,24 @@ admin_fileproc (callerdat, finfo)
rev = xstrdup (p);
}
revnum = RCS_gettag (rcs, rev, 0, NULL);
free (rev);
if (revnum != NULL)
{
n = findnode (rcs->versions, revnum);
if (revnum == NULL || n == NULL)
free (revnum);
}
else
n = NULL;
if (n == NULL)
{
error (0, 0,
"%s: can't set state of nonexisting revision %s",
rcs->path,
rev);
if (revnum != NULL)
free (revnum);
free (rev);
status = 1;
continue;
}
free (rev);
delta = (RCSVers *) n->data;
free (delta->state);
delta->state = tag;
@ -788,6 +833,7 @@ admin_fileproc (callerdat, finfo)
msg = p;
n = findnode (rcs->versions, rev);
free (rev);
delta = (RCSVers *) n->data;
if (delta->text == NULL)
{
@ -823,12 +869,7 @@ admin_fileproc (callerdat, finfo)
additional message is to make it clear that the previous problems
caused CVS to forget about the idea of modifying the RCS file. */
error (0, 0, "cannot modify RCS file for `%s'", finfo->file);
/* Upon failure, we want to abandon any changes made to the
RCS data structure. Forcing a reparse does the trick,
but leaks memory and is kludgey. Should we export
free_rcsnode_contents for this purpose? */
RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL);
RCS_abandon (rcs);
}
exitfunc:

View File

@ -37,11 +37,10 @@
#include "cvs.h"
static char *findslash PROTO((char *start, char *p));
static int checkout_proc PROTO((int *pargc, char **argv, char *where,
static int checkout_proc PROTO((int argc, char **argv, char *where,
char *mwhere, char *mfile, int shorten,
int local_specified, char *omodule,
char *msg));
static int safe_location PROTO((void));
static const char *const checkout_usage[] =
{
@ -95,6 +94,7 @@ static char *join_rev2 = NULL;
static int join_tags_validated = 0;
static char *preload_update_dir = NULL;
static char *history_name = NULL;
static enum mtype m_type;
int
checkout (argc, argv)
@ -111,7 +111,6 @@ checkout (argc, argv)
char *where = NULL;
char *valid_options;
const char *const *valid_usage;
enum mtype m_type;
/*
* A smaller subset of options are allowed for the export command, which
@ -233,7 +232,7 @@ checkout (argc, argv)
if (where && pipeout)
error (1, 0, "-d and -p are mutually exclusive");
if (strcmp (command_name, "export") == 0)
if (m_type == EXPORT)
{
if (!tag && !date)
error (1, 0, "must specify a tag or date");
@ -294,7 +293,7 @@ checkout (argc, argv)
send_arg("-A");
if (!shorten)
send_arg("-N");
if (checkout_prune_dirs && strcmp (command_name, "export") != 0)
if (checkout_prune_dirs && m_type == CHECKOUT)
send_arg("-P");
client_prune_dirs = checkout_prune_dirs;
if (cat)
@ -325,10 +324,7 @@ checkout (argc, argv)
client_nonexpanded_setup ();
}
send_to_server (strcmp (command_name, "export") == 0 ?
"export\012" : "co\012",
0);
send_to_server (m_type == EXPORT ? "export\012" : "co\012", 0);
return get_responses_and_close ();
}
#endif /* CLIENT_SUPPORT */
@ -355,7 +351,7 @@ 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 (m_type == CHECKOUT && !pipeout)
{
if (tag && date)
{
@ -379,7 +375,10 @@ checkout (argc, argv)
return (err);
}
static int
/* FIXME: This is and emptydir_name are in checkout.c for historical
reasons, probably want to move them. */
int
safe_location ()
{
char *current;
@ -455,7 +454,12 @@ build_one_dir (repository, dirpath, sticky)
{
FILE *fp;
if (!isfile (CVSADM) && strcmp (command_name, "export") != 0)
if (isfile (CVSADM))
{
if (m_type == EXPORT)
error (1, 0, "cannot export into a working directory");
}
else if (m_type == CHECKOUT)
{
/* I suspect that this check could be omitted. */
if (!isdir (repository))
@ -471,7 +475,7 @@ build_one_dir (repository, dirpath, sticky)
then rewrite it later via WriteTag, once
we've had a chance to call RCS_nodeisbranch
on each file. */
0, 1))
0, 1, 1))
return;
if (!noexec)
@ -492,9 +496,9 @@ build_one_dir (repository, dirpath, sticky)
*/
/* ARGSUSED */
static int
checkout_proc (pargc, argv, where_orig, mwhere, mfile, shorten,
checkout_proc (argc, argv, where_orig, mwhere, mfile, shorten,
local_specified, omodule, msg)
int *pargc;
int argc;
char **argv;
char *where_orig;
char *mwhere;
@ -504,6 +508,7 @@ checkout_proc (pargc, argv, where_orig, mwhere, mfile, shorten,
char *omodule;
char *msg;
{
char *myargv[2];
int err = 0;
int which;
char *cp;
@ -665,26 +670,10 @@ checkout_proc (pargc, argv, where_orig, mwhere, mfile, shorten,
{
/* It's a file, which means we have to screw around with
argv. */
int i;
/* Paranoia check. */
if (*pargc > 1)
{
error (0, 0, "checkout_proc: trashing argv elements!");
for (i = 1; i < *pargc; i++)
{
error (0, 0, "checkout_proc: argv[%d] `%s'",
i, argv[i]);
}
}
for (i = 1; i < *pargc; i++)
free (argv[i]);
argv[1] = xstrdup (mfile);
(*pargc) = 2;
myargv[0] = argv[0];
myargv[1] = mfile;
argc = 2;
argv = myargv;
}
free (path);
}
@ -745,7 +734,7 @@ internal error: %s doesn't start with %s in checkout_proc",
NT, &c, if the user specifies '\'. Likewise for the call
to findslash. */
cp = where + strlen (where);
while (1)
while (cp > where)
{
struct dir_to_build *new;
@ -761,7 +750,7 @@ internal error: %s doesn't start with %s in checkout_proc",
last path element we create should be the top-level
directory. */
if (cp - where)
if (cp > where)
{
strncpy (new->dirpath, where, cp - where);
new->dirpath[cp - where] = '\0';
@ -769,7 +758,7 @@ internal error: %s doesn't start with %s in checkout_proc",
else
{
/* where should always be at least one character long. */
assert (strlen (where));
assert (where[0] != '\0');
strcpy (new->dirpath, "/");
}
new->next = head;
@ -841,10 +830,11 @@ internal error: %s doesn't start with %s in checkout_proc",
{
/* It's a directory in the repository! */
char *rp = strrchr (reposcopy, '/');
char *rp;
/* We'll always be below CVSROOT, but check for
paranoia's sake. */
rp = strrchr (reposcopy, '/');
if (rp == NULL)
error (1, 0,
"internal error: %s doesn't contain a slash",
@ -890,7 +880,7 @@ internal error: %s doesn't start with %s in checkout_proc",
{
/* It may be argued that we shouldn't set any sticky
bits for the top-level repository. FIXME? */
build_one_dir (CVSroot_directory, ".", *pargc <= 1);
build_one_dir (CVSroot_directory, ".", argc <= 1);
#ifdef SERVER_SUPPORT
/* We _always_ want to have a top-level admin
@ -912,7 +902,7 @@ internal error: %s doesn't start with %s in checkout_proc",
contain a CVS subdir yet, but all the others contain
CVS and Entries.Static files */
if (build_dirs_and_chdir (head, *pargc <= 1) != 0)
if (build_dirs_and_chdir (head, argc <= 1) != 0)
{
error (0, 0, "ignoring module %s", omodule);
err = 1;
@ -925,14 +915,15 @@ internal error: %s doesn't start with %s in checkout_proc",
{
FILE *fp;
if (!noexec && *pargc > 1)
if (!noexec && argc > 1)
{
/* I'm not sure whether this check is redundant. */
if (!isdir (repository))
error (1, 0, "there is no repository %s", repository);
Create_Admin (".", preload_update_dir, repository,
(char *) NULL, (char *) NULL, 0, 0);
(char *) NULL, (char *) NULL, 0, 0,
m_type == CHECKOUT);
fp = open_file (CVSADM_ENTSTAT, "w+");
if (fclose(fp) == EOF)
error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
@ -955,13 +946,16 @@ internal error: %s doesn't start with %s in checkout_proc",
then rewrite it later via WriteTag, once
we've had a chance to call RCS_nodeisbranch
on each file. */
0, 0);
0, 0, m_type == CHECKOUT);
}
}
else
{
char *repos;
if (m_type == EXPORT)
error (1, 0, "cannot export into working directory");
/* get the contents of the previously existing repository */
repos = Name_Repository ((char *) NULL, preload_update_dir);
if (fncmp (repository, repos) != 0)
@ -993,7 +987,7 @@ internal error: %s doesn't start with %s in checkout_proc",
which = W_REPOS;
if (tag != NULL && !tag_validated)
{
tag_check_valid (tag, *pargc - 1, argv + 1, 0, aflag, NULL);
tag_check_valid (tag, argc - 1, argv + 1, 0, aflag, NULL);
tag_validated = 1;
}
}
@ -1002,7 +996,7 @@ internal error: %s doesn't start with %s in checkout_proc",
which = W_LOCAL | W_REPOS;
if (tag != NULL && !tag_validated)
{
tag_check_valid (tag, *pargc - 1, argv + 1, 0, aflag,
tag_check_valid (tag, argc - 1, argv + 1, 0, aflag,
repository);
tag_validated = 1;
}
@ -1014,10 +1008,10 @@ internal error: %s doesn't start with %s in checkout_proc",
if (! join_tags_validated)
{
if (join_rev1 != NULL)
tag_check_valid_join (join_rev1, *pargc - 1, argv + 1, 0, aflag,
tag_check_valid_join (join_rev1, argc - 1, argv + 1, 0, aflag,
repository);
if (join_rev2 != NULL)
tag_check_valid_join (join_rev2, *pargc - 1, argv + 1, 0, aflag,
tag_check_valid_join (join_rev2, argc - 1, argv + 1, 0, aflag,
repository);
join_tags_validated = 1;
}
@ -1027,12 +1021,12 @@ internal error: %s doesn't start with %s in checkout_proc",
* update recursion processor. We will be recursive unless either local
* only was specified, or we were passed arguments
*/
if (!(local_specified || *pargc > 1))
if (!(local_specified || argc > 1))
{
if (strcmp (command_name, "export") != 0 && !pipeout)
if (m_type == CHECKOUT && !pipeout)
history_write ('O', preload_update_dir, history_name, where,
repository);
else if (strcmp (command_name, "export") == 0 && !pipeout)
else if (m_type == EXPORT && !pipeout)
history_write ('E', preload_update_dir, tag ? tag : date, where,
repository);
err += do_update (0, (char **) NULL, options, tag, date,
@ -1050,7 +1044,7 @@ internal error: %s doesn't start with %s in checkout_proc",
/* we are only doing files, so register them */
entries = Entries_Open (0, NULL);
for (i = 1; i < *pargc; i++)
for (i = 1; i < argc; i++)
{
char *line;
Vers_TS *vers;
@ -1087,12 +1081,12 @@ internal error: %s doesn't start with %s in checkout_proc",
}
/* Don't log "export", just regular "checkouts" */
if (strcmp (command_name, "export") != 0 && !pipeout)
if (m_type == CHECKOUT && !pipeout)
history_write ('O', preload_update_dir, history_name, where,
repository);
/* go ahead and call update now that everything is set */
err += do_update (*pargc - 1, argv + 1, options, tag, date,
err += do_update (argc - 1, argv + 1, options, tag, date,
force_tag_match, local_specified, 1 /* update -d */,
aflag, checkout_prune_dirs, pipeout, which, join_rev1,
join_rev2, preload_update_dir);
@ -1109,15 +1103,13 @@ findslash (start, p)
char *start;
char *p;
{
while (p >= start && *p != '/')
p--;
/* FIXME: indexing off the start of the array like this is *NOT*
OK according to ANSI, and will break some of the time on certain
segmented architectures. */
if (p < start)
return (NULL);
else
return (p);
for (;;)
{
if (*p == '/') return p;
if (p == start) break;
--p;
}
return NULL;
}
/* Return a newly malloc'd string containing a pathname for CVSNULLREPOS,
@ -1185,5 +1177,14 @@ build_dirs_and_chdir (dirs, sticky)
}
out:
while (dirs != NULL)
{
if (dirs->repository != NULL)
free (dirs->repository);
nextdir = dirs->next;
free (dirs->dirpath);
free (dirs);
dirs = nextdir;
}
return retval;
}

View File

@ -1,3 +1,5 @@
/* JT thinks BeOS is worth the trouble. */
/* CVS client-related stuff.
This program is free software; you can redistribute it and/or modify
@ -60,7 +62,6 @@ extern char *strerror ();
#if HAVE_KERBEROS
#define CVS_PORT 1999
#if HAVE_KERBEROS
#include <krb.h>
extern char *krb_realmofhost ();
@ -74,8 +75,6 @@ static Key_schedule sched;
#endif /* HAVE_KERBEROS */
#endif /* HAVE_KERBEROS */
#ifdef HAVE_GSSAPI
#ifdef HAVE_GSSAPI_H
@ -1115,7 +1114,7 @@ call_in_directory (pathname, func, data)
strcpy (r, "/.");
Create_Admin (".", ".", repo, (char *) NULL,
(char *) NULL, 0, 1);
(char *) NULL, 0, 1, 1);
free (repo);
}
@ -1252,7 +1251,7 @@ warning: server is not creating directories one at a time");
strcpy (r, reposdirname);
Create_Admin (dir, dir, repo,
(char *)NULL, (char *)NULL, 0, 0);
(char *)NULL, (char *)NULL, 0, 0, 1);
free (repo);
b = strrchr (dir, '/');
@ -1760,6 +1759,7 @@ update_entries (data_arg, ent_list, short_pathname, filename)
}
free (mode_string);
free (scratch_entries);
free (entries_line);
/* The Mode, Mod-time, and Checksum responses should not carry
@ -1847,7 +1847,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (use_gzip)
{
if (gunzip_and_write (fd, short_pathname, buf, size))
if (gunzip_and_write (fd, short_pathname,
(unsigned char *) buf, size))
error (1, 0, "aborting due to compression error");
}
else if (write (fd, buf, size) != size)
@ -2025,6 +2026,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
free (mode_string);
free (buf);
free (scratch_entries);
free (entries_line);
return;
}
@ -2123,8 +2126,8 @@ update_entries (data_arg, ent_list, short_pathname, filename)
if (file_timestamp)
free (file_timestamp);
free (scratch_entries);
}
free (scratch_entries);
free (entries_line);
}
@ -2490,7 +2493,11 @@ handle_set_checkin_prog (args, len)
{
char *prog;
struct save_prog *p;
read_line (&prog);
if (strcmp (command_name, "export") == 0)
return;
p = (struct save_prog *) xmalloc (sizeof (struct save_prog));
p->next = checkin_progs;
p->dir = xstrdup (args);
@ -2505,7 +2512,11 @@ handle_set_update_prog (args, len)
{
char *prog;
struct save_prog *p;
read_line (&prog);
if (strcmp (command_name, "export") == 0)
return;
p = (struct save_prog *) xmalloc (sizeof (struct save_prog));
p->next = update_progs;
p->dir = xstrdup (args);
@ -2683,7 +2694,7 @@ send_repository (dir, repos, update_dir)
{
Node *n;
n = getnode ();
n->type = UNKNOWN;
n->type = NT_UNKNOWN;
n->key = xstrdup (update_dir);
n->data = NULL;
@ -3594,19 +3605,15 @@ get_responses_and_close ()
&& waitpid (rsh_pid, (int *) 0, 0) == -1)
error (1, errno, "waiting for process %d", rsh_pid);
buf_free (to_server);
buf_free (from_server);
server_started = 0;
/* see if we need to sleep before returning */
/* see if we need to sleep before returning to avoid time-stamp races */
if (last_register_time)
{
time_t now;
for (;;)
{
(void) time (&now);
if (now != last_register_time) break;
sleep (1); /* to avoid time-stamp races */
}
while (time ((time_t *) NULL) == last_register_time)
sleep (1);
}
return errs;
@ -3774,6 +3781,7 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
int port_number;
struct sockaddr_in client_sai;
struct hostent *hostinfo;
char no_passwd = 0; /* gets set if no password found */
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == -1)
@ -3818,6 +3826,14 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
/* Get the password, probably from ~/.cvspass. */
password = get_cvs_password ();
/* Send the empty string by default. This is so anonymous CVS
access doesn't require client to have done "cvs login". */
if (password == NULL)
{
no_passwd = 1;
password = scramble ("");
}
/* Announce that we're starting the authorization protocol. */
if (send (sock, begin, strlen (begin), 0) < 0)
@ -3841,8 +3857,8 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
if (send (sock, end, strlen (end), 0) < 0)
error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
/* Paranoia. */
memset (password, 0, strlen (password));
/* Paranoia. */
memset (password, 0, strlen (password));
}
{
@ -3935,20 +3951,28 @@ connect_to_pserver (tofdp, fromfdp, verify_only, do_gssapi)
return;
rejected:
error (0, 0,
"authorization failed: server %s rejected access to %s for user %s",
CVSroot_hostname, CVSroot_directory, CVSroot_username);
/* Output a special error message if authentication was attempted
with no password -- the user should be made aware that they may
have missed a step. */
if (no_passwd)
{
error (0, 0,
"used empty password; try \"cvs login\" with a real password");
}
if (shutdown (sock, 2) < 0)
{
error (0, 0,
"authorization failed: server %s rejected access",
CVSroot_hostname);
error (1, 0,
error (0, 0,
"shutdown() failed (server %s): %s",
CVSroot_hostname,
SOCK_STRERROR (SOCK_ERRNO));
}
error (1, 0,
"authorization failed: server %s rejected access",
CVSroot_hostname);
error_exit();
}
#endif /* AUTH_CLIENT_SUPPORT */
@ -4111,9 +4135,16 @@ connect_to_gserver (sock, hostinfo)
if (stat_maj != GSS_S_COMPLETE && stat_maj != GSS_S_CONTINUE_NEEDED)
{
OM_uint32 message_context;
OM_uint32 new_stat_min;
message_context = 0;
gss_display_status (&stat_min, stat_maj, GSS_C_GSS_CODE,
gss_display_status (&new_stat_min, stat_maj, GSS_C_GSS_CODE,
GSS_C_NULL_OID, &message_context, &tok_out);
error (0, 0, "GSSAPI authentication failed: %s",
(char *) tok_out.value);
message_context = 0;
gss_display_status (&new_stat_min, stat_min, GSS_C_MECH_CODE,
GSS_C_NULL_OID, &message_context, &tok_out);
error (1, 0, "GSSAPI authentication failed: %s",
(char *) tok_out.value);
@ -4137,7 +4168,29 @@ connect_to_gserver (sock, hostinfo)
recv_bytes (sock, cbuf, 2);
need = ((cbuf[0] & 0xff) << 8) | (cbuf[1] & 0xff);
assert (need <= sizeof buf);
if (need > sizeof buf)
{
int got;
/* This usually means that the server sent us an error
message. Read it byte by byte and print it out.
FIXME: This is a terrible error handling strategy.
However, even if we fix the server, we will still
want to do this to work with older servers. */
buf[0] = cbuf[0];
buf[1] = cbuf[1];
got = recv (sock, buf + 2, sizeof buf - 2, 0);
if (got < 0)
error (1, 0, "recv() from server %s: %s",
CVSroot_hostname, SOCK_STRERROR (SOCK_ERRNO));
buf[got + 2] = '\0';
if (buf[got + 1] == '\n')
buf[got + 1] = '\0';
error (1, 0, "error from server %s: %s", CVSroot_hostname,
buf);
}
recv_bytes (sock, buf, need);
tok_in.length = need;
}
@ -4171,7 +4224,7 @@ send_variable_proc (node, closure)
void
start_server ()
{
int tofd, fromfd;
int tofd, fromfd, rootless;
char *log = getenv ("CVS_CLIENT_LOG");
@ -4350,7 +4403,8 @@ the :server: access method is not supported by this port of CVS");
stored_mode = NULL;
}
if (strcmp (command_name, "init") != 0)
rootless = (strcmp (command_name, "init") == 0);
if (!rootless)
{
send_to_server ("Root ", 0);
send_to_server (CVSroot_directory, 0);
@ -4474,7 +4528,7 @@ the :server: access method is not supported by this port of CVS");
}
}
if (cvsencrypt)
if (cvsencrypt && !rootless)
{
#ifdef ENCRYPTION
/* Turn on encryption before turning on compression. We do
@ -4521,7 +4575,7 @@ the :server: access method is not supported by this port of CVS");
#endif /* ! ENCRYPTION */
}
if (gzip_level)
if (gzip_level && !rootless)
{
if (supported_request ("Gzip-stream"))
{
@ -4563,7 +4617,7 @@ the :server: access method is not supported by this port of CVS");
}
}
if (cvsauthenticate && ! cvsencrypt)
if (cvsauthenticate && ! cvsencrypt && !rootless)
{
/* Turn on authentication after turning on compression, so
that we can compress the authentication information. We
@ -4594,7 +4648,7 @@ the :server: access method is not supported by this port of CVS");
}
#ifdef FILENAMES_CASE_INSENSITIVE
if (supported_request ("Case"))
if (supported_request ("Case") && !rootless)
send_to_server ("Case\012", 0);
#endif
@ -4964,6 +5018,7 @@ struct send_data
int build_dirs;
int force;
int no_contents;
int backup_modified;
};
static int send_fileproc PROTO ((void *callerdat, struct file_info *finfo));
@ -5085,6 +5140,18 @@ warning: ignoring -k options due to server limitations");
}
else
send_modified (filename, finfo->fullname, vers);
if (args->backup_modified)
{
char *bakname;
bakname = backup_file (filename, vers->vn_user);
/* This behavior is sufficiently unexpected to
justify overinformativeness, I think. */
if (! really_quiet)
printf ("(Locally modified %s moved to %s)\n",
filename, bakname);
free (bakname);
}
}
else
{
@ -5193,9 +5260,6 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
dir_exists = isdir (cvsadm_name);
free (cvsadm_name);
/* initialize the ignore list for this directory */
ignlist = getlist ();
/*
* If there is an empty directory (e.g. we are doing `cvs add' on a
* newly-created directory), the server still needs to know about it.
@ -5211,6 +5275,9 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
char *repos = Name_Repository (dir, update_dir);
send_a_repository (dir, repos, update_dir);
free (repos);
/* initialize the ignore list for this directory */
ignlist = getlist ();
}
else
{
@ -5235,6 +5302,29 @@ send_dirent_proc (callerdat, dir, repository, update_dir, entries)
return (dir_exists ? R_PROCESS : R_SKIP_ALL);
}
static int send_dirleave_proc PROTO ((void *, char *, int, char *, List *));
/*
* send_dirleave_proc () is called back by the recursion code upon leaving
* a directory. All it does is delete the ignore list if it hasn't already
* been done (by send_filesdone_proc).
*/
/* ARGSUSED */
static int
send_dirleave_proc (callerdat, dir, err, update_dir, entries)
void *callerdat;
char *dir;
int err;
char *update_dir;
List *entries;
{
/* Delete the ignore list if it hasn't already been done. */
if (ignlist)
dellist (&ignlist);
return err;
}
/*
* Send each option in a string to the server, one by one.
* This assumes that the options are separated by spaces, for example
@ -5426,9 +5516,10 @@ send_files (argc, argv, local, aflag, flags)
args.build_dirs = flags & SEND_BUILD_DIRS;
args.force = flags & SEND_FORCE;
args.no_contents = flags & SEND_NO_CONTENTS;
args.backup_modified = flags & BACKUP_MODIFIED_FILES;
err = start_recursion
(send_fileproc, send_filesdoneproc,
send_dirent_proc, (DIRLEAVEPROC)NULL, (void *) &args,
send_dirent_proc, send_dirleave_proc, (void *) &args,
argc, argv, local, W_LOCAL, aflag, 0, (char *)NULL, 0);
if (err)
error_exit ();

View File

@ -109,6 +109,7 @@ send_files PROTO((int argc, char **argv, int local, int aflag,
#define SEND_BUILD_DIRS 1
#define SEND_FORCE 2
#define SEND_NO_CONTENTS 4
#define BACKUP_MODIFIED_FILES 8
/* Send an argument to the remote server. */
void

View File

@ -263,6 +263,7 @@ find_fileproc (callerdat, finfo)
else
error (0, 0, "use `%s add' to create an entry for %s",
program_name, finfo->fullname);
freevers_ts (&vers);
return 1;
}
else if (vers->ts_user != NULL
@ -284,6 +285,7 @@ find_fileproc (callerdat, finfo)
cases. FIXME: we probably should be printing a message and
returning 1 for many of those cases (but I'm not sure
exactly which ones). */
freevers_ts (&vers);
return 0;
}
@ -421,28 +423,12 @@ commit (argc, argv)
/* some checks related to the "-F logfile" option */
if (logfile)
{
int n, logfd;
struct stat statbuf;
size_t size = 0, len;
if (saved_message)
error (1, 0, "cannot specify both a message and a log file");
/* FIXME: Why is this binary? Needs more investigation. */
if ((logfd = CVS_OPEN (logfile, O_RDONLY | OPEN_BINARY)) < 0)
error (1, errno, "cannot open log file %s", logfile);
if (fstat(logfd, &statbuf) < 0)
error (1, errno, "cannot find size of log file %s", logfile);
saved_message = xmalloc (statbuf.st_size + 1);
/* FIXME: Should keep reading until EOF, rather than assuming the
first read gets the whole thing. */
if ((n = read (logfd, saved_message, statbuf.st_size + 1)) < 0)
error (1, errno, "cannot read log message from %s", logfile);
(void) close (logfd);
saved_message[n] = '\0';
get_file (logfile, logfile, "r", &saved_message, &size, &len);
}
#ifdef CLIENT_SUPPORT
@ -473,11 +459,14 @@ commit (argc, argv)
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). */
dellist (&find_args.ulist);
return 0;
}
/* Now we keep track of which files we actually are going to
operate on, and only work with those files in the future.
@ -583,6 +572,8 @@ commit (argc, argv)
previous versions of client/server CVS, but it probably is a Good
Thing, or at least Not Such A Bad Thing. */
send_file_names (find_args.argc, find_args.argv, 0);
free (find_args.argv);
dellist (&find_args.ulist);
send_to_server ("ci\012", 0);
err = get_responses_and_close ();
@ -672,16 +663,11 @@ commit (argc, argv)
Lock_Cleanup ();
dellist (&mulist);
/* see if we need to sleep before returning to avoid time-stamp races */
if (last_register_time)
{
time_t now;
for (;;)
{
(void) time (&now);
if (now != last_register_time) break;
sleep (1); /* to avoid time-stamp races */
}
while (time ((time_t *) NULL) == last_register_time)
sleep (1);
}
return (err);
@ -794,6 +780,12 @@ check_fileproc (callerdat, finfo)
size_t cvsroot_len = strlen (CVSroot_directory);
if (!finfo->repository)
{
error (0, 0, "nothing known about `%s'", finfo->fullname);
return (1);
}
if (strncmp (finfo->repository, CVSroot_directory, cvsroot_len) == 0
&& ISDIRSEP (finfo->repository[cvsroot_len])
&& strncmp (finfo->repository + cvsroot_len + 1,
@ -1290,6 +1282,8 @@ commit_fileproc (callerdat, finfo)
{
if (finfo->rcs == NULL)
error (1, 0, "internal error: no parsed RCS file");
if (ci->rev)
free (ci->rev);
ci->rev = RCS_whatbranch (finfo->rcs, ci->tag);
err = Checkin ('A', finfo, finfo->rcs->path, ci->rev,
ci->tag, ci->options, saved_message);
@ -1400,6 +1394,8 @@ commit_fileproc (callerdat, finfo)
}
}
}
if (SIG_inCrSect ())
SIG_endCrSect ();
return (err);
}
@ -1500,6 +1496,7 @@ commit_filesdoneproc (callerdat, err, repository, update_dir, entries)
cvs_output (": Executing '", 0);
run_print (stdout);
cvs_output ("'\n", 0);
cvs_flushout ();
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
free (repos);
}
@ -1582,8 +1579,10 @@ commit_dirleaveproc (callerdat, dir, err, update_dir, entries)
this being a confusing feature! */
if (err == 0 && write_dirtag != NULL)
{
char *repos = Name_Repository (dir, update_dir);
WriteTag (NULL, write_dirtag, NULL, write_dirnonbranch,
update_dir, Name_Repository (dir, update_dir));
update_dir, repos);
free (repos);
}
return (err);
@ -1751,6 +1750,9 @@ remove_file (finfo, tag, message)
"failed to commit dead revision for `%s'", finfo->fullname);
return (1);
}
/* At this point, the file has been committed as removed. We should
probably tell the history file about it */
history_write ('R', NULL, finfo->rcs->head, finfo->file, finfo->repository);
if (rev != NULL)
free (rev);
@ -1962,6 +1964,11 @@ checkaddfile (file, repository, tag, options, rcsnode)
sprintf (rcs, "%s/%s%s", repository, file, RCSEXT);
/* Begin a critical section around the code that spans the
first commit on the trunk of a file that's already been
committed on a branch. */
SIG_beginCrSect ();
if (RCS_setattic (rcsfile, 0))
{
retval = 1;
@ -2044,74 +2051,76 @@ checkaddfile (file, repository, tag, options, rcsnode)
newfile = 1;
if (desc != NULL)
free (desc);
}
/* when adding a file for the first time, and using a tag, we need
to create a dead revision on the trunk. */
if (adding_on_branch && newfile)
{
char *tmp;
FILE *fp;
/* move the new file out of the way. */
fname = xmalloc (strlen (file) + sizeof (CVSADM)
+ sizeof (CVSPREFIX) + 10);
(void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
rename_file (file, fname);
/* Create empty FILE. Can't use copy_file with a DEVNULL
argument -- copy_file now ignores device files. */
fp = fopen (file, "w");
if (fp == NULL)
error (1, errno, "cannot open %s for writing", file);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", file);
tmp = xmalloc (strlen (file) + strlen (tag) + 80);
/* commit a dead revision. */
(void) sprintf (tmp, "file %s was initially added on branch %s.",
file, tag);
retcode = RCS_checkin (rcsfile, NULL, tmp, NULL,
RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
free (tmp);
if (retcode != 0)
{
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
"could not create initial dead revision %s", rcs);
retval = 1;
goto out;
}
/* put the new file back where it was */
rename_file (fname, file);
free (fname);
/* double-check that the file was written correctly */
freercsnode (&rcsfile);
rcsfile = RCS_parse (file, repository);
if (rcsfile == NULL)
{
error (0, 0, "could not read %s", rcs);
retval = 1;
goto out;
}
if (rcsnode != NULL)
{
assert (*rcsnode == NULL);
*rcsnode = rcsfile;
}
/* and lock it once again. */
if (lock_RCS (file, rcsfile, NULL, repository))
{
error (0, 0, "cannot lock `%s'.", rcs);
retval = 1;
goto out;
}
}
/* when adding a file for the first time, and using a tag, we need
to create a dead revision on the trunk. */
if (adding_on_branch)
{
if (newfile)
{
char *tmp;
FILE *fp;
/* move the new file out of the way. */
fname = xmalloc (strlen (file) + sizeof (CVSADM)
+ sizeof (CVSPREFIX) + 10);
(void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
rename_file (file, fname);
/* Create empty FILE. Can't use copy_file with a DEVNULL
argument -- copy_file now ignores device files. */
fp = fopen (file, "w");
if (fp == NULL)
error (1, errno, "cannot open %s for writing", file);
if (fclose (fp) < 0)
error (0, errno, "cannot close %s", file);
tmp = xmalloc (strlen (file) + strlen (tag) + 80);
/* commit a dead revision. */
(void) sprintf (tmp, "file %s was initially added on branch %s.",
file, tag);
retcode = RCS_checkin (rcsfile, NULL, tmp, NULL,
RCS_FLAGS_DEAD | RCS_FLAGS_QUIET);
free (tmp);
if (retcode != 0)
{
error (retcode == -1 ? 1 : 0, retcode == -1 ? errno : 0,
"could not create initial dead revision %s", rcs);
retval = 1;
goto out;
}
/* put the new file back where it was */
rename_file (fname, file);
free (fname);
/* double-check that the file was written correctly */
freercsnode (&rcsfile);
rcsfile = RCS_parse (file, repository);
if (rcsfile == NULL)
{
error (0, 0, "could not read %s", rcs);
retval = 1;
goto out;
}
if (rcsnode != NULL)
*rcsnode = rcsfile;
/* and lock it once again. */
if (lock_RCS (file, rcsfile, NULL, repository))
{
error (0, 0, "cannot lock `%s'.", rcs);
retval = 1;
goto out;
}
}
/* when adding with a tag, we need to stub a branch, if it
doesn't already exist. */
@ -2194,6 +2203,8 @@ checkaddfile (file, repository, tag, options, rcsnode)
retval = 0;
out:
if (retval != 0 && SIG_inCrSect ())
SIG_endCrSect ();
free (rcs);
return retval;
}

View File

@ -22,7 +22,8 @@
don't print warnings; all errors are fatal then. */
int
Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn)
Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn,
dotemplate)
char *dir;
char *update_dir;
char *repository;
@ -30,6 +31,7 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn)
char *date;
int nonbranch;
int warn;
int dotemplate;
{
FILE *fout;
char *cp;
@ -168,7 +170,7 @@ Create_Admin (dir, update_dir, repository, tag, date, nonbranch, warn)
WriteTag (dir, tag, date, nonbranch, update_dir, repository);
#ifdef SERVER_SUPPORT
if (server_active)
if (server_active && dotemplate)
{
server_template (update_dir, repository);
}

View File

@ -390,6 +390,7 @@ extern List *root_directories;
extern char *current_root;
extern char *emptydir_name PROTO ((void));
extern int safe_location PROTO ((void));
extern int trace; /* Show all commands */
extern int noexec; /* Don't modify disk anywhere */
@ -499,7 +500,7 @@ void *valloc PROTO((size_t bytes));
time_t get_date PROTO((char *date, struct timeb *now));
extern int Create_Admin PROTO ((char *dir, char *update_dir,
char *repository, char *tag, char *date,
int nonbranch, int warn));
int nonbranch, int warn, int dotemplate));
extern int expand_at_signs PROTO ((char *, off_t, FILE *));
/* Locking subsystem (implemented in lock.c). */
@ -525,7 +526,7 @@ void cat_module PROTO((int status));
void check_entries PROTO((char *dir));
void close_module PROTO((DBM * db));
void copy_file PROTO((const char *from, const char *to));
void fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
void fperrmsg PROTO((FILE * fp, int status, int errnum, char *message,...));
void free_names PROTO((int *pargc, char *argv[]));
extern int ign_name PROTO ((char *name));
@ -546,6 +547,7 @@ 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));
char *backup_file PROTO((const char *file, const char *suffix));
/* 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
conventions regarding wildcard syntax. It might be desirable to change the
@ -577,7 +579,7 @@ void do_editor PROTO((char *dir, char **messagep,
void do_verify PROTO((char *message, char *repository));
typedef int (*CALLBACKPROC) PROTO((int *pargc, char *argv[], char *where,
typedef int (*CALLBACKPROC) PROTO((int argc, char *argv[], char *where,
char *mwhere, char *mfile, int shorten, int local_specified,
char *omodule, char *msg));
@ -636,6 +638,7 @@ int start_recursion PROTO((FILEPROC fileproc, FILESDONEPROC filesdoneproc,
int dosrcs));
void SIG_beginCrSect PROTO((void));
void SIG_endCrSect PROTO((void));
int SIG_inCrSect PROTO((void));
void read_cvsrc PROTO((int *argc, char ***argv, char *cmdname));
char *make_message_rcslegal PROTO((char *message));
@ -853,6 +856,7 @@ extern int cvsremove PROTO((int argc, char **argv));
extern int rtag PROTO((int argc, char **argv));
extern int cvsstatus PROTO((int argc, char **argv));
extern int cvstag PROTO((int argc, char **argv));
extern int version PROTO((int argc, char **argv));
extern unsigned long int lookup_command_attribute PROTO((char *));
@ -869,6 +873,8 @@ 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 *));
#include "server.h"
/* From server.c and documented there. */
extern void cvs_output PROTO ((const char *, size_t));
extern void cvs_output_binary PROTO ((char *, size_t));
@ -876,7 +882,3 @@ extern void cvs_outerr PROTO ((const char *, size_t));
extern void cvs_flusherr PROTO ((void));
extern void cvs_flushout PROTO ((void));
extern void cvs_output_tagged PROTO ((char *, char *));
#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
#include "server.h"
#endif

View File

@ -427,6 +427,15 @@ edit (argc, argv)
setting_tcommit = 1;
}
if (strpbrk (hostname, "+,>;=\t\n") != NULL)
error (1, 0,
"host name (%s) contains an invalid character (+,>;=\\t\\n)",
hostname);
if (strpbrk (CurDir, "+,>;=\t\n") != NULL)
error (1, 0,
"current directory (%s) contains an invalid character (+,>;=\\t\\n)",
CurDir);
/* No need to readlock since we aren't doing anything to the
repository. */
err = start_recursion (edit_fileproc, (FILESDONEPROC) NULL,
@ -553,6 +562,15 @@ unedit_fileproc (callerdat, finfo)
return 0;
}
static const char *const unedit_usage[] =
{
"Usage: %s %s [-lR] [files...]\n",
"-l: Local directory only, not recursive\n",
"-R: Process directories recursively\n",
"(Specify the --help global option for a list of other help options)\n",
NULL
};
int
unedit (argc, argv)
int argc;
@ -563,7 +581,7 @@ unedit (argc, argv)
int err;
if (argc == -1)
usage (edit_usage);
usage (unedit_usage);
optind = 0;
while ((c = getopt (argc, argv, "+lR")) != -1)
@ -578,7 +596,7 @@ unedit (argc, argv)
break;
case '?':
default:
usage (edit_usage);
usage (unedit_usage);
break;
}
}
@ -1060,6 +1078,7 @@ editors_fileproc (callerdat, finfo)
cvs_output ("\n", 1);
}
out:;
free (them);
return 0;
}

View File

@ -807,7 +807,8 @@ Subdirs_Known (entries)
if (!noexec)
{
/* Create Entries.Log so that Entries_Close will do something. */
fp = CVS_FOPEN (CVSADM_ENTLOG, "a");
entfilename = CVSADM_ENTLOG;
fp = CVS_FOPEN (entfilename, "a");
if (fp == NULL)
{
int save_errno = errno;
@ -821,7 +822,7 @@ Subdirs_Known (entries)
else
{
if (fclose (fp) == EOF)
error (1, errno, "cannot close %s", CVSADM_ENTLOG);
error (1, errno, "cannot close %s", entfilename);
}
}
}

View File

@ -64,7 +64,8 @@ extern char *strerror ();
void
error_exit PROTO ((void))
{
Lock_Cleanup();
rcs_cleanup ();
Lock_Cleanup ();
#ifdef SERVER_SUPPORT
if (server_active)
server_cleanup (0);
@ -122,7 +123,7 @@ error (status, errnum, message, va_alist)
int num;
unsigned int unum;
int ch;
unsigned char buf[100];
char buf[100];
cvs_outerr (program_name, 0);
if (command_name && *command_name)
@ -201,9 +202,9 @@ error (status, errnum, message, va_alist)
/* VARARGS */
void
#if defined (HAVE_VPRINTF) && defined (__STDC__)
fperror (FILE *fp, int status, int errnum, char *message, ...)
fperrmsg (FILE *fp, int status, int errnum, char *message, ...)
#else
fperror (fp, status, errnum, message, va_alist)
fperrmsg (fp, status, errnum, message, va_alist)
FILE *fp;
int status;
int errnum;

View File

@ -126,7 +126,7 @@ fileattr_read ()
any line other than the first for that filename. This
is the way that CVS has behaved since file attributes
were first introduced. */
free (newnode);
freenode (newnode);
}
else if (line[0] == 'D')
{
@ -513,6 +513,7 @@ fileattr_write ()
FILE *fp;
char *fname;
mode_t omask;
struct unrecog *p;
if (!attrs_modified)
return;
@ -616,17 +617,10 @@ fileattr_write ()
}
/* Then any other attributes. */
while (unrecog_head != NULL)
for (p = unrecog_head; p != NULL; p = p->next)
{
struct unrecog *p;
p = unrecog_head;
fputs (p->line, fp);
fputs ("\012", fp);
unrecog_head = p->next;
free (p->line);
free (p);
}
if (fclose (fp) < 0)
@ -649,4 +643,11 @@ fileattr_free ()
if (fileattr_default_attrs != NULL)
free (fileattr_default_attrs);
fileattr_default_attrs = NULL;
while (unrecog_head)
{
struct unrecog *p = unrecog_head;
unrecog_head = p->next;
free (p->line);
free (p);
}
}

View File

@ -51,9 +51,13 @@ copy_file (from, to)
if (isdevice (from))
{
#if defined(HAVE_MKNOD) && defined(HAVE_ST_RDEV)
if (stat (from, &sb) < 0)
error (1, errno, "cannot stat %s", from);
mknod (to, sb.st_mode, sb.st_rdev);
#else
error (1, 0, "cannot copy device files on this system (%s)", from);
#endif
}
else
{
@ -620,10 +624,15 @@ xcmp (file1, file2)
numbers match. */
if (S_ISBLK (sb1.st_mode) || S_ISCHR (sb1.st_mode))
{
#ifdef HAVE_ST_RDEV
if (sb1.st_rdev == sb2.st_rdev)
return 0;
else
return 1;
#else
error (1, 0, "cannot compare device files on this system (%s and %s)",
file1, file2);
#endif
}
if ((fd1 = open (file1, O_RDONLY)) < 0)

View File

@ -63,7 +63,7 @@ lookup_file_by_inode (filepath)
/* inodestr contains the hexadecimal representation of an
inode, so it requires two bytes of text to represent
each byte of the inode number. */
inodestr = (char *) xmalloc (2*sizeof(ino_t)*sizeof(char) + 1);
inodestr = (char *) xmalloc (2*sizeof(ino_t) + 1);
if (stat (file, &sb) < 0)
{
if (existence_error (errno))
@ -85,7 +85,7 @@ lookup_file_by_inode (filepath)
if (hp == NULL)
{
hp = getnode ();
hp->type = UNKNOWN;
hp->type = NT_UNKNOWN;
hp->key = inodestr;
hp->data = (char *) getlist();
hp->delproc = dellist;
@ -100,7 +100,7 @@ lookup_file_by_inode (filepath)
if (p == NULL)
{
p = getnode();
p->type = UNKNOWN;
p->type = NT_UNKNOWN;
p->key = xstrdup (filepath);
p->data = NULL;
(void) addnode ((List *) hp->data, p);
@ -128,7 +128,7 @@ update_hardlink_info (file)
/* file is a relative pathname; assume it's from the current
working directory. */
char *dir = xgetwd();
path = xmalloc (sizeof(char) * (strlen(dir) + strlen(file) + 2));
path = xmalloc (strlen(dir) + strlen(file) + 2);
sprintf (path, "%s/%s", dir, file);
free (dir);
}
@ -176,8 +176,7 @@ list_linked_files_on_disk (file)
else
{
char *dir = xgetwd();
path = (char *) xmalloc (sizeof(char) *
(strlen(dir) + strlen(file) + 2));
path = (char *) xmalloc (strlen(dir) + strlen(file) + 2);
sprintf (path, "%s/%s", dir, file);
free (dir);
}
@ -193,7 +192,7 @@ list_linked_files_on_disk (file)
/* inodestr contains the hexadecimal representation of an
inode, so it requires two bytes of text to represent
each byte of the inode number. */
inodestr = (char *) xmalloc (2*sizeof(ino_t)*sizeof(char) + 1);
inodestr = (char *) xmalloc (2*sizeof(ino_t) + 1);
sprintf (inodestr, "%lx", (unsigned long) sb.st_ino);
/* Make sure the files linked to this inode are sorted. */
@ -280,7 +279,7 @@ find_checkedout_proc (node, data)
/* Look at this file in the hardlist and see whether the checked_out
field is 1, meaning that it has been checked out during this CVS run. */
path = (char *)
xmalloc (sizeof(char) * (strlen (dir) + strlen (node->key) + 2));
xmalloc (strlen (dir) + strlen (node->key) + 2);
sprintf (path, "%s/%s", dir, node->key);
link = lookup_file_by_inode (path);
free (path);

View File

@ -102,7 +102,7 @@ dellist (listp)
{
/* put the nodes into the cache */
#ifndef NOCACHE
p->type = UNKNOWN;
p->type = NT_UNKNOWN;
p->next = nodecache;
nodecache = p;
#else
@ -147,7 +147,7 @@ getnode ()
/* always make it clean */
memset ((char *) p, 0, sizeof (Node));
p->type = UNKNOWN;
p->type = NT_UNKNOWN;
return (p);
}
@ -211,7 +211,7 @@ freenode (p)
/* then put it in the cache */
#ifndef NOCACHE
p->type = UNKNOWN;
p->type = NT_UNKNOWN;
p->next = nodecache;
nodecache = p;
#else
@ -456,7 +456,7 @@ nodetypestring (type)
Ntype type;
{
switch (type) {
case UNKNOWN: return("UNKNOWN");
case NT_UNKNOWN: return("UNKNOWN");
case HEADER: return("HEADER");
case ENTRIES: return("ENTRIES");
case FILES: return("FILES");
@ -470,6 +470,7 @@ nodetypestring (type)
case FILEATTR: return("FILEATTR");
case VARIABLE: return("VARIABLE");
case RCSFIELD: return("RCSFIELD");
case RCSCMPFLD: return("RCSCMPFLD");
}
return("<trash>");

View File

@ -16,9 +16,9 @@
*/
enum ntype
{
UNKNOWN, HEADER, ENTRIES, FILES, LIST, RCSNODE,
NT_UNKNOWN, HEADER, ENTRIES, FILES, LIST, RCSNODE,
RCSVERS, DIRS, UPDATE, LOCK, NDBMNODE, FILEATTR,
VARIABLE, RCSFIELD
VARIABLE, RCSFIELD, RCSCMPFLD
};
typedef enum ntype Ntype;

View File

@ -195,7 +195,7 @@ static struct hrec
} *hrec_head;
static char *fill_hrec PROTO((char *line, struct hrec * hr));
static void fill_hrec PROTO((char *line, struct hrec * hr));
static int accept_hrec PROTO((struct hrec * hr, struct hrec * lr));
static int select_hrec PROTO((struct hrec * hr));
static int sort_order PROTO((const PTR l, const PTR r));
@ -233,6 +233,8 @@ static short tz_local;
static time_t tz_seconds_east_of_GMT;
static char *tz_name = "+0000";
char *logHistory = ALL_REC_TYPES;
/* -r, -t, or -b options, malloc'd. These are "" if the option in
question is not specified or is overridden by another option. The
main reason for using "" rather than NULL is historical. Together
@ -288,9 +290,9 @@ static const char *const history_usg[] =
" -o Checked out modules\n",
" -m <module> Look for specified module (repeatable)\n",
" -x [TOEFWUCGMAR] Extract by record type\n",
" -e Everything (same as -x, but all record types)\n",
" Flags:\n",
" -a All users (Default is self)\n",
" -e Everything (same as -x, but all record types)\n",
" -l Last modified (committed or modified report)\n",
" -w Working directory must match\n",
" Options:\n",
@ -523,13 +525,17 @@ history (argc, argv)
break;
}
}
c = optind; /* Save the handled option count */
argc -= optind;
argv += optind;
for (i = 0; i < argc; i++)
save_file ("", argv[i], (char *) NULL);
/* ================ Now analyze the arguments a bit */
if (!report_count)
v_checkout++;
else if (report_count > 1)
error (1, 0, "Only one report type allowed from: \"-Tcomx\".");
error (1, 0, "Only one report type allowed from: \"-Tcomxe\".");
#ifdef CLIENT_SUPPORT
if (client_active)
@ -613,7 +619,8 @@ history (argc, argv)
* If the user has not specified a date oriented flag ("Since"), sort
* by Repository/file before date. Default is "just" date.
*/
if (!since_date && !*since_rev && !*since_tag && !*backto)
if (last_entry
|| (!since_date && !*since_rev && !*since_tag && !*backto))
{
repos_sort++;
file_sort++;
@ -642,7 +649,8 @@ history (argc, argv)
/* See comments in "modified" above */
if (!last_entry && user_list)
user_sort++;
if (!since_date && !*since_rev && !*since_tag && !*backto)
if (last_entry
|| (!since_date && !*since_rev && !*since_tag && !*backto))
file_sort++;
}
@ -657,11 +665,6 @@ history (argc, argv)
(void) strcat (rec_types, "T");
}
argc -= c;
argv += c;
for (i = 0; i < argc; i++)
save_file ("", argv[i], (char *) NULL);
if (histfile)
fname = xstrdup (histfile);
else
@ -673,7 +676,11 @@ history (argc, argv)
}
read_hrecs (fname);
qsort ((PTR) hrec_head, hrec_count, sizeof (struct hrec), sort_order);
if(hrec_count>0)
{
qsort ((PTR) hrec_head, hrec_count,
sizeof (struct hrec), sort_order);
}
report_hrecs ();
free (fname);
if (since_date != NULL)
@ -706,6 +713,8 @@ history_write (type, update_dir, revs, name, repository)
if (logoff) /* History is turned off by cmd line switch */
return;
if ( strchr(logHistory, type) == NULL )
return;
fname = xmalloc (strlen (CVSroot_directory) + sizeof (CVSROOTADM)
+ sizeof (CVSROOTADM_HISTORY) + 10);
(void) sprintf (fname, "%s/%s/%s", CVSroot_directory,
@ -725,7 +734,14 @@ history_write (type, update_dir, revs, name, repository)
goto out;
fd = CVS_OPEN (fname, O_WRONLY | O_APPEND | O_CREAT | OPEN_BINARY, 0666);
if (fd < 0)
error (1, errno, "cannot open history file: %s", fname);
{
if (! really_quiet)
{
error (0, errno, "warning: cannot write to history file %s",
fname);
}
goto out;
}
repos = Short_Repository (repository);
@ -965,27 +981,26 @@ expand_modules ()
*
* Split it into 7 parts and drop the parts into a "struct hrec".
* Return a pointer to the character following the newline.
*
*/
#define NEXT_BAR(here) do { while (isspace((unsigned char) *line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return(rtn); *(line - 1) = '\0'; } while (0)
#define NEXT_BAR(here) do { while (isspace(*line)) line++; hr->here = line; while ((c = *line++) && c != '|') ; if (!c) return; *(line - 1) = '\0'; } while (0)
static char *
static void
fill_hrec (line, hr)
char *line;
struct hrec *hr;
{
char *cp, *rtn;
char *cp;
int c;
int off;
static int idx = 0;
unsigned long date;
memset ((char *) hr, 0, sizeof (*hr));
while (isspace ((unsigned char) *line))
line++;
if (!(rtn = strchr (line, '\n')))
return ("");
*rtn++ = '\0';
hr->type = line++;
(void) sscanf (line, "%lx", &date);
@ -993,7 +1008,7 @@ fill_hrec (line, hr)
while (*line && strchr ("0123456789abcdefABCDEF", *line))
line++;
if (*line == '\0')
return (rtn);
return;
line++;
NEXT_BAR (user);
@ -1012,27 +1027,38 @@ fill_hrec (line, hr)
if (strchr ("FOET", *(hr->type)))
hr->mod = line;
NEXT_BAR (file); /* This returns ptr to next line or final '\0' */
return (rtn); /* If it falls through, go on to next record */
NEXT_BAR (file);
}
#ifndef STAT_BLOCKSIZE
#if HAVE_ST_BLKSIZE
#define STAT_BLOCKSIZE(s) (s).st_blksize
#else
#define STAT_BLOCKSIZE(s) (4 * 1024)
#endif
#endif
/* read_hrecs's job is to read the history file and fill in all the "hrec"
* (history record) array elements with the ones we need to print.
*
* Logic:
* - Read the whole history file into a single buffer.
* - Walk through the buffer, parsing lines out of the buffer.
* 1. Split line into pointer and integer fields in the "next" hrec.
* 2. Apply tests to the hrec to see if it is wanted.
* 3. If it *is* wanted, bump the hrec pointer down by one.
* - Read a block from the file.
* - Walk through the block parsing line into hr records.
* - if the hr isn't used, free its strings, if it is, bump the hrec counter
* - at the end of a block, copy the end of the current block to the start
* of space for the next block, then read in the next block. If we get less
* than the whole block, we're done.
*/
static void
read_hrecs (fname)
char *fname;
{
char *cp, *cp2;
int i, fd;
struct hrec *hr;
unsigned char *cpstart, *cp, *nl;
char *hrline;
int i;
int fd;
struct stat st_buf;
if ((fd = CVS_OPEN (fname, O_RDONLY | OPEN_BINARY)) < 0)
@ -1041,54 +1067,75 @@ read_hrecs (fname)
if (fstat (fd, &st_buf) < 0)
error (1, errno, "can't stat history file");
/* Exactly enough space for lines data */
if (!(i = st_buf.st_size))
if (!(st_buf.st_size))
error (1, 0, "history file is empty");
cp = xmalloc (i + 2);
if (read (fd, cp, i) != i)
error (1, errno, "cannot read log file");
(void) close (fd);
if (*(cp + i - 1) != '\n')
{
*(cp + i) = '\n'; /* Make sure last line ends in '\n' */
i++;
}
*(cp + i) = '\0';
for (cp2 = cp; cp2 - cp < i; cp2++)
{
if (*cp2 != '\n' && !isprint ((unsigned char) *cp2))
*cp2 = ' ';
}
cpstart = xmalloc (2 * STAT_BLOCKSIZE(st_buf));
cpstart[0] = '\0';
cp = cpstart;
hrec_max = HREC_INCREMENT;
hrec_head = (struct hrec *) xmalloc (hrec_max * sizeof (struct hrec));
hrec_head = xmalloc (hrec_max * sizeof (struct hrec));
while (*cp)
for (;;)
{
for (nl = cp; *nl && *nl != '\n'; nl++)
if (!isprint(*nl)) *nl = ' ';
if (!*nl)
{
if (nl - cp >= STAT_BLOCKSIZE(st_buf))
{
error(1, 0, "history line too long (> %lu)",
(unsigned long) STAT_BLOCKSIZE(st_buf));
}
if (nl > cp)
memmove (cpstart, cp, nl - cp);
nl = cpstart + (nl - cp);
cp = cpstart;
i = read (fd, nl, STAT_BLOCKSIZE(st_buf));
if (i > 0)
{
nl[i] = '\0';
continue;
}
if (i < 0)
error (1, errno, "error reading history file");
if (nl == cp) break;
nl[1] = '\0';
}
*nl = '\0';
if (hrec_count == hrec_max)
{
struct hrec *old_head = hrec_head;
hrec_max += HREC_INCREMENT;
hrec_head = (struct hrec *) xrealloc ((char *) hrec_head,
hrec_max * sizeof (struct hrec));
if (hrec_head != old_head)
{
if (last_since_tag)
last_since_tag = hrec_head + (last_since_tag - old_head);
if (last_backto)
last_backto = hrec_head + (last_backto - old_head);
}
hrec_head = xrealloc ((char *) hrec_head,
hrec_max * sizeof (struct hrec));
if (last_since_tag)
last_since_tag = hrec_head + (last_since_tag - old_head);
if (last_backto)
last_backto = hrec_head + (last_backto - old_head);
}
hr = hrec_head + hrec_count;
cp = fill_hrec (cp, hr); /* cp == next line or '\0' at end of buffer */
/* fill_hrec dates from when history read the entire
history file in one chunk, and then records were pulled out
by pointing to the various parts of this big chunk. This is
why there are ugly hacks here: I don't want to completely
re-write the whole history stuff right now. */
if (select_hrec (hr))
hrline = xstrdup ((char *)cp);
fill_hrec (hrline, &hrec_head[hrec_count]);
if (select_hrec (&hrec_head[hrec_count]))
hrec_count++;
else
free(hrline);
cp = nl + 1;
}
free (cpstart);
close (fd);
/* Special selection problem: If "since_tag" is set, we have saved every
* record from the 1st occurrence of "since_tag", when we want to save
@ -1169,11 +1216,10 @@ select_hrec (hr)
if (since_date)
{
char *ourdate = date_from_time_t (hr->date);
if (RCS_datecmp (ourdate, since_date) < 0)
return (0);
count = RCS_datecmp (ourdate, since_date);
free (ourdate);
if (count < 0)
return (0);
}
else if (*since_rev)
{
@ -1426,9 +1472,9 @@ report_hrecs ()
else
tm = localtime (&(lr->date));
(void) printf ("%c %02d/%02d %02d:%02d %s %-*s", ty, tm->tm_mon + 1,
tm->tm_mday, tm->tm_hour, tm->tm_min, tz_name,
user_len, lr->user);
(void) printf ("%c %04d-%02d-%02d %02d:%02d %s %-*s", ty,
tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
tm->tm_min, tz_name, user_len, lr->user);
workdir = xmalloc (strlen (lr->dir) + strlen (lr->end) + 10);
(void) sprintf (workdir, "%s%s", lr->dir, lr->end);

View File

@ -333,9 +333,7 @@ ign_dir_add (name)
(dir_ign_max + 1) * sizeof (char *));
}
dir_ign_list[dir_ign_current] = name;
dir_ign_current += 1 ;
dir_ign_list[dir_ign_current++] = xstrdup (name);
}
@ -414,9 +412,9 @@ ignore_files (ilist, entries, update_dir, proc)
{
file = dp->d_name;
if (strcmp (file, ".") == 0 || strcmp (file, "..") == 0)
continue;
goto continue_loop;
if (findnode_fn (ilist, file) != NULL)
continue;
goto continue_loop;
if (subdirs)
{
Node *node;
@ -437,14 +435,14 @@ ignore_files (ilist, entries, update_dir, proc)
dir = isdir (p);
free (p);
if (dir)
continue;
goto continue_loop;
}
}
/* We could be ignoring FIFOs and other files which are neither
regular files nor directories here. */
if (ign_name (file))
continue;
goto continue_loop;
if (
#ifdef DT_DIR
@ -455,9 +453,12 @@ ignore_files (ilist, entries, update_dir, proc)
if (
#ifdef DT_DIR
dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN &&
dp->d_type == DT_DIR
|| (dp->d_type == DT_UNKNOWN && S_ISDIR (sb.st_mode))
#else
S_ISDIR (sb.st_mode)
#endif
S_ISDIR(sb.st_mode))
)
{
if (! subdirs)
{
@ -468,7 +469,7 @@ ignore_files (ilist, entries, update_dir, proc)
if (isdir (temp))
{
free (temp);
continue;
goto continue_loop;
}
free (temp);
}
@ -476,16 +477,20 @@ ignore_files (ilist, entries, update_dir, proc)
#ifdef S_ISLNK
else if (
#ifdef DT_DIR
dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
dp->d_type == DT_LNK
|| (dp->d_type == DT_UNKNOWN && S_ISLNK(sb.st_mode))
#else
S_ISLNK (sb.st_mode)
#endif
S_ISLNK(sb.st_mode))
)
{
continue;
goto continue_loop;
}
#endif
}
(*proc) (file, xdir);
continue_loop:
errno = 0;
}
if (errno != 0)

View File

@ -266,12 +266,22 @@ import (argc, argv)
client_import_setup (repository);
err = import_descend (message, argv[1], argc - 2, argv + 2);
client_import_done ();
if (message)
free (message);
free (repository);
free (vbranch);
free (vhead);
send_to_server ("import\012", 0);
err += get_responses_and_close ();
return err;
}
#endif
if (!safe_location ())
{
error (1, 0, "attempt to import the repository");
}
/*
* Make all newly created directories writable. Should really use a more
* sophisticated security mechanism here.
@ -453,9 +463,12 @@ import_descend (message, vtag, targc, targv)
}
else if (
#ifdef DT_DIR
dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
dp->d_type == DT_LNK
|| (dp->d_type == DT_UNKNOWN && islink (dp->d_name))
#else
islink (dp->d_name)
#endif
islink (dp->d_name))
)
{
add_log ('L', dp->d_name);
err++;
@ -725,8 +738,8 @@ add_rev (message, rcs, vfile, vers)
{
if (!noexec)
{
fperror (logfp, 0, status == -1 ? ierrno : 0,
"ERROR: Check-in of %s failed", rcs->path);
fperrmsg (logfp, 0, status == -1 ? ierrno : 0,
"ERROR: Check-in of %s failed", rcs->path);
error (0, status == -1 ? ierrno : 0,
"ERROR: Check-in of %s failed", rcs->path);
}
@ -765,8 +778,8 @@ add_tags (rcs, vfile, vtag, targc, targv)
if ((retcode = RCS_settag(rcs, vtag, vbranch)) != 0)
{
ierrno = errno;
fperror (logfp, 0, retcode == -1 ? ierrno : 0,
"ERROR: Failed to set tag %s in %s", vtag, rcs->path);
fperrmsg (logfp, 0, retcode == -1 ? ierrno : 0,
"ERROR: Failed to set tag %s in %s", vtag, rcs->path);
error (0, retcode == -1 ? ierrno : 0,
"ERROR: Failed to set tag %s in %s", vtag, rcs->path);
return (1);
@ -789,9 +802,9 @@ add_tags (rcs, vfile, vtag, targc, targv)
else
{
ierrno = errno;
fperror (logfp, 0, retcode == -1 ? ierrno : 0,
"WARNING: Couldn't add tag %s to %s", targv[i],
rcs->path);
fperrmsg (logfp, 0, retcode == -1 ? ierrno : 0,
"WARNING: Couldn't add tag %s to %s", targv[i],
rcs->path);
error (0, retcode == -1 ? ierrno : 0,
"WARNING: Couldn't add tag %s to %s", targv[i],
rcs->path);
@ -1054,7 +1067,14 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
stat the file before opening it. -twp */
if (CVS_LSTAT (userfile, &sb) < 0)
error (1, errno, "cannot lstat %s", user);
{
/* not fatal, continue import */
if (add_logfp != NULL)
fperrmsg (add_logfp, 0, errno,
"ERROR: cannot lstat file %s", userfile);
error (0, errno, "cannot lstat file %s", userfile);
goto read_error;
}
file_type = sb.st_mode & S_IFMT;
fpuser = NULL;
@ -1069,8 +1089,8 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
{
/* not fatal, continue import */
if (add_logfp != NULL)
fperror (add_logfp, 0, errno,
"ERROR: cannot read file %s", userfile);
fperrmsg (add_logfp, 0, errno,
"ERROR: cannot read file %s", userfile);
error (0, errno, "ERROR: cannot read file %s", userfile);
goto read_error;
}
@ -1202,12 +1222,18 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
case S_IFREG: break;
case S_IFCHR:
case S_IFBLK:
#ifdef HAVE_ST_RDEV
if (fprintf (fprcs, "special\t%s %lu;\012",
(file_type == S_IFCHR
? "character"
: "block"),
(unsigned long) sb.st_rdev) < 0)
goto write_error;
#else
error (0, 0,
"can't import %s: unable to import device files on this system",
userfile);
#endif
break;
default:
error (0, 0,
@ -1253,12 +1279,18 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
case S_IFREG: break;
case S_IFCHR:
case S_IFBLK:
#ifdef HAVE_ST_RDEV
if (fprintf (fprcs, "special\t%s %lu;\012",
(file_type == S_IFCHR
? "character"
: "block"),
(unsigned long) sb.st_rdev) < 0)
goto write_error;
#else
error (0, 0,
"can't import %s: unable to import device files on this system",
userfile);
#endif
break;
default:
error (0, 0,
@ -1377,8 +1409,8 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
{
ierrno = errno;
if (add_logfp != NULL)
fperror (add_logfp, 0, ierrno,
"WARNING: cannot change mode of file %s", rcs);
fperrmsg (add_logfp, 0, ierrno,
"WARNING: cannot change mode of file %s", rcs);
error (0, ierrno, "WARNING: cannot change mode of file %s", rcs);
err++;
}
@ -1397,14 +1429,14 @@ add_rcs_file (message, rcs, user, add_vhead, key_opt,
if (fclose (fpuser) < 0)
error (0, errno, "cannot close %s", user);
if (add_logfp != NULL)
fperror (add_logfp, 0, ierrno, "ERROR: cannot write file %s", rcs);
fperrmsg (add_logfp, 0, ierrno, "ERROR: cannot write file %s", rcs);
error (0, ierrno, "ERROR: cannot write file %s", rcs);
if (ierrno == ENOSPC)
{
if (CVS_UNLINK (rcs) < 0)
error (0, errno, "cannot remove %s", rcs);
if (add_logfp != NULL)
fperror (add_logfp, 0, 0, "ERROR: out of space - aborting");
fperrmsg (add_logfp, 0, 0, "ERROR: out of space - aborting");
error (1, 0, "ERROR: out of space - aborting");
}
read_error:
@ -1513,7 +1545,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
return (0);
if (save_cwd (&cwd))
{
fperror (logfp, 0, 0, "ERROR: cannot get working directory");
fperrmsg (logfp, 0, 0, "ERROR: cannot get working directory");
return (1);
}
@ -1544,7 +1576,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
if ( CVS_CHDIR (dir) < 0)
{
ierrno = errno;
fperror (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository);
fperrmsg (logfp, 0, ierrno, "ERROR: cannot chdir to %s", repository);
error (0, ierrno, "ERROR: cannot chdir to %s", repository);
err = 1;
goto out;
@ -1559,9 +1591,9 @@ import_descend_dir (message, dir, vtag, targc, targv)
(void) sprintf (rcs, "%s%s", repository, RCSEXT);
if (isfile (repository) || isfile(rcs))
{
fperror (logfp, 0, 0,
"ERROR: %s is a file, should be a directory!",
repository);
fperrmsg (logfp, 0, 0,
"ERROR: %s is a file, should be a directory!",
repository);
error (0, 0, "ERROR: %s is a file, should be a directory!",
repository);
err = 1;
@ -1570,8 +1602,8 @@ import_descend_dir (message, dir, vtag, targc, targv)
if (noexec == 0 && CVS_MKDIR (repository, 0777) < 0)
{
ierrno = errno;
fperror (logfp, 0, ierrno,
"ERROR: cannot mkdir %s -- not added", repository);
fperrmsg (logfp, 0, ierrno,
"ERROR: cannot mkdir %s -- not added", repository);
error (0, ierrno,
"ERROR: cannot mkdir %s -- not added", repository);
err = 1;

View File

@ -175,8 +175,12 @@ lock_name (repository, name)
assert (CVSroot_directory != NULL);
assert (strncmp (repository, CVSroot_directory,
strlen (CVSroot_directory)) == 0);
short_repos = repository + strlen (CVSroot_directory);
assert (*short_repos++ == '/');
short_repos = repository + strlen (CVSroot_directory) + 1;
if (strcmp (repository, CVSroot_directory) == 0)
short_repos = ".";
else
assert (short_repos[-1] == '/');
retval = xmalloc (strlen (lock_dir)
+ strlen (short_repos)
@ -755,8 +759,8 @@ set_lock (lock, will_wait)
if (errno != EEXIST)
{
error (0, errno,
"failed to create lock directory in repository `%s'",
lock->repository);
"failed to create lock directory for `%s' (%s)",
lock->repository, masterlock);
return (L_ERROR);
}

View File

@ -149,6 +149,47 @@ static const char *const log_usage[] =
NULL
};
#ifdef CLIENT_SUPPORT
/* Helper function for send_arg_list. */
static int send_one PROTO ((Node *, void *));
static int
send_one (node, closure)
Node *node;
void *closure;
{
char *option = (char *) closure;
send_to_server ("Argument ", 0);
send_to_server (option, 0);
if (strcmp (node->key, "@@MYSELF") == 0)
/* It is a bare -w option. Note that we must send it as
-w rather than messing with getcaller() or something (which on
the client will return garbage). */
;
else
send_to_server (node->key, 0);
send_to_server ("\012", 0);
return 0;
}
/* For each element in ARG, send an argument consisting of OPTION
concatenated with that element. */
static void send_arg_list PROTO ((char *, List *));
static void
send_arg_list (option, arg)
char *option;
List *arg;
{
if (arg == NULL)
return;
walklist (arg, send_one, (void *)option);
}
#endif
int
cvslog (argc, argv)
int argc;
@ -158,12 +199,13 @@ cvslog (argc, argv)
int err = 0;
int local = 0;
struct log_data log_data;
struct option_revlist *rl, **prl;
struct option_revlist **prl;
if (argc == -1)
usage (log_usage);
memset (&log_data, 0, sizeof log_data);
prl = &log_data.revlist;
optind = 0;
while ((c = getopt (argc, argv, "+bd:hlNRr::s:tw::")) != -1)
@ -189,12 +231,8 @@ cvslog (argc, argv)
log_data.nameonly = 1;
break;
case 'r':
rl = log_parse_revlist (optarg);
for (prl = &log_data.revlist;
*prl != NULL;
prl = &(*prl)->next)
;
*prl = rl;
*prl = log_parse_revlist (optarg);
prl = &(*prl)->next;
break;
case 's':
log_parse_list (&log_data.statelist, optarg);
@ -206,7 +244,7 @@ cvslog (argc, argv)
if (optarg != NULL)
log_parse_list (&log_data.authorlist, optarg);
else
log_parse_list (&log_data.authorlist, getcaller ());
log_parse_list (&log_data.authorlist, "@@MYSELF");
break;
case '?':
default:
@ -220,18 +258,97 @@ cvslog (argc, argv)
#ifdef CLIENT_SUPPORT
if (client_active)
{
int i;
struct datelist *p;
struct option_revlist *rp;
char datetmp[MAXDATELEN];
/* We're the local client. Fire up the remote server. */
start_server ();
ign_setup ();
for (i = 1; i < argc && argv[i][0] == '-'; i++)
send_arg (argv[i]);
if (log_data.default_branch)
send_arg ("-b");
send_files (argc - i, argv + i, local, 0, SEND_NO_CONTENTS);
send_file_names (argc - i, argv + i, SEND_EXPAND_WILD);
while (log_data.datelist != NULL)
{
p = log_data.datelist;
log_data.datelist = p->next;
send_to_server ("Argument -d\012", 0);
send_to_server ("Argument ", 0);
date_to_internet (datetmp, p->start);
send_to_server (datetmp, 0);
if (p->inclusive)
send_to_server ("<=", 0);
else
send_to_server ("<", 0);
date_to_internet (datetmp, p->end);
send_to_server (datetmp, 0);
send_to_server ("\012", 0);
if (p->start)
free (p->start);
if (p->end)
free (p->end);
free (p);
}
while (log_data.singledatelist != NULL)
{
p = log_data.singledatelist;
log_data.singledatelist = p->next;
send_to_server ("Argument -d\012", 0);
send_to_server ("Argument ", 0);
date_to_internet (datetmp, p->end);
send_to_server (datetmp, 0);
send_to_server ("\012", 0);
if (p->end)
free (p->end);
free (p);
}
if (log_data.header)
send_arg ("-h");
if (local)
send_arg("-l");
if (log_data.notags)
send_arg("-N");
if (log_data.nameonly)
send_arg("-R");
if (log_data.long_header)
send_arg("-t");
while (log_data.revlist != NULL)
{
rp = log_data.revlist;
log_data.revlist = rp->next;
send_to_server ("Argument -r", 0);
if (rp->branchhead)
{
if (rp->first != NULL)
send_to_server (rp->first, 0);
send_to_server (".", 1);
}
else
{
if (rp->first != NULL)
send_to_server (rp->first, 0);
send_to_server (":", 1);
if (rp->last != NULL)
send_to_server (rp->last, 0);
}
send_to_server ("\012", 0);
if (rp->first)
free (rp->first);
if (rp->last)
free (rp->last);
free (rp);
}
send_arg_list ("-s", log_data.statelist);
dellist (&log_data.statelist);
send_arg_list ("-w", log_data.authorlist);
dellist (&log_data.authorlist);
send_files (argc - optind, argv + optind, local, 0, SEND_NO_CONTENTS);
send_file_names (argc - optind, argv + optind, SEND_EXPAND_WILD);
send_to_server ("log\012", 0);
err = get_responses_and_close ();
@ -239,11 +356,50 @@ cvslog (argc, argv)
}
#endif
/* OK, now that we know we are local/server, we can resolve @@MYSELF
into our user name. */
if (findnode (log_data.authorlist, "@@MYSELF") != NULL)
log_parse_list (&log_data.authorlist, getcaller ());
err = start_recursion (log_fileproc, (FILESDONEPROC) NULL, log_dirproc,
(DIRLEAVEPROC) NULL, (void *) &log_data,
argc - optind, argv + optind, local,
W_LOCAL | W_REPOS | W_ATTIC, 0, 1,
(char *) NULL, 1);
while (log_data.revlist)
{
struct option_revlist *rl = log_data.revlist->next;
if (log_data.revlist->first)
free (log_data.revlist->first);
if (log_data.revlist->last)
free (log_data.revlist->last);
free (log_data.revlist);
log_data.revlist = rl;
}
while (log_data.datelist)
{
struct datelist *nd = log_data.datelist->next;
if (log_data.datelist->start)
free (log_data.datelist->start);
if (log_data.datelist->end)
free (log_data.datelist->end);
free (log_data.datelist);
log_data.datelist = nd;
}
while (log_data.singledatelist)
{
struct datelist *nd = log_data.singledatelist->next;
if (log_data.singledatelist->start)
free (log_data.singledatelist->start);
if (log_data.singledatelist->end)
free (log_data.singledatelist->end);
free (log_data.singledatelist);
log_data.singledatelist = nd;
}
dellist (&log_data.statelist);
dellist (&log_data.authorlist);
return (err);
}
@ -255,77 +411,65 @@ static struct option_revlist *
log_parse_revlist (argstring)
const char *argstring;
{
char *copy;
char *orig_copy, *copy;
struct option_revlist *ret, **pr;
/* Unfortunately, rlog accepts -r without an argument to mean that
latest revision on the default branch, so we must support that
for compatibility. */
if (argstring == NULL)
{
ret = (struct option_revlist *) xmalloc (sizeof *ret);
ret->first = NULL;
ret->last = NULL;
ret->next = NULL;
ret->branchhead = 0;
return ret;
}
argstring = "";
ret = NULL;
pr = &ret;
/* Copy the argument into memory so that we can change it. We
don't want to change the argument because, at least as of this
writing, we will use it if we send the arguments to the server.
We never bother to free up our copy. */
copy = xstrdup (argstring);
writing, we will use it if we send the arguments to the server. */
orig_copy = copy = xstrdup (argstring);
while (copy != NULL)
{
char *comma;
char *cp;
char *first, *last;
struct option_revlist *r;
comma = strchr (copy, ',');
if (comma != NULL)
*comma++ = '\0';
first = copy;
cp = strchr (copy, ':');
if (cp == NULL)
last = copy;
else
{
*cp++ = '\0';
last = cp;
}
if (*first == '\0')
first = NULL;
if (*last == '\0')
last = NULL;
r = (struct option_revlist *) xmalloc (sizeof *r);
r->next = NULL;
r->first = first;
r->last = last;
if (first != last
|| first[strlen (first) - 1] != '.')
{
r->branchhead = 0;
}
r->first = copy;
r->branchhead = 0;
r->last = strchr (copy, ':');
if (r->last != NULL)
*r->last++ = '\0';
else
{
r->branchhead = 1;
first[strlen (first) - 1] = '\0';
r->last = r->first;
if (r->first[0] != '\0' && r->first[strlen (r->first) - 1] == '.')
{
r->branchhead = 1;
r->first[strlen (r->first) - 1] = '\0';
}
}
if (*r->first == '\0')
r->first = NULL;
if (*r->last == '\0')
r->last = NULL;
if (r->first != NULL)
r->first = xstrdup (r->first);
if (r->last != NULL)
r->last = xstrdup (r->last);
*pr = r;
pr = &r->next;
copy = comma;
}
free (orig_copy);
return ret;
}
@ -342,8 +486,7 @@ log_parse_date (log_data, argstring)
/* Copy the argument into memory so that we can change it. We
don't want to change the argument because, at least as of this
writing, we will use it if we send the arguments to the server. */
copy = xstrdup (argstring);
orig_copy = copy;
orig_copy = copy = xstrdup (argstring);
while (copy != NULL)
{
struct datelist *nd, **pd;

View File

@ -12,6 +12,12 @@
#ifdef AUTH_CLIENT_SUPPORT /* This covers the rest of the file. */
#ifdef HAVE_GETPASSPHRASE
#define GETPASS getpassphrase
#else
#define GETPASS getpass
#endif
/* There seems to be very little agreement on which system header
getpass is declared in. With a lot of fancy autoconfiscation,
we could perhaps detect this, but for now we'll just rely on
@ -20,7 +26,7 @@
varadic, believe it or not). On Cray, getpass will be declared
in either stdlib.h or unistd.h. */
#ifndef _CRAY
extern char *getpass ();
extern char *GETPASS ();
#endif
#ifndef CVS_PASSWORD_FILE
@ -142,7 +148,7 @@ login (argc, argv)
fflush (stdout);
passfile = construct_cvspass_filename ();
typed_password = getpass ("CVS password: ");
typed_password = GETPASS ("CVS password: ");
typed_password = scramble (typed_password);
/* Force get_cvs_password() to use this one (when the client
@ -289,14 +295,15 @@ login (argc, argv)
}
/* Returns the _scrambled_ password. The server must descramble
before hashing and comparing. */
before hashing and comparing. If password file not found, or
password not found in the file, just return NULL. */
char *
get_cvs_password ()
{
int found_it = 0;
int root_len;
char *password;
char *linebuf = (char *) NULL;
char *password = NULL;
char *linebuf = NULL;
size_t linebuf_len;
FILE *fp;
char *passfile;
@ -339,11 +346,10 @@ get_cvs_password ()
passfile = construct_cvspass_filename ();
fp = CVS_FOPEN (passfile, "r");
if (fp == NULL)
if (fp == NULL)
{
error (0, errno, "could not open %s", passfile);
free (passfile);
error (1, 0, "use \"cvs login\" to log in first");
return NULL;
}
root_len = strlen (CVSroot_original);
@ -369,23 +375,19 @@ get_cvs_password ()
char *tmp;
strtok (linebuf, " ");
password = strtok (NULL, "\n");
tmp = strtok (NULL, "\n");
if (tmp == NULL)
error (1, 0, "bad entry in %s for %s", passfile, CVSroot_original);
/* Give it permanent storage. */
tmp = xstrdup (password);
memset (password, 0, strlen (password));
free (linebuf);
return tmp;
password = xstrdup (tmp);
memset (tmp, 0, strlen (password));
}
else
{
if (linebuf)
free (linebuf);
error (0, 0, "cannot find password");
error (1, 0, "use \"cvs login\" to log in first");
}
/* NOTREACHED */
return NULL;
if (linebuf)
free (linebuf);
free (passfile);
return password;
}
static const char *const logout_usage[] =
@ -395,7 +397,7 @@ static const char *const logout_usage[] =
NULL
};
/* Remove any entry for the CVSRoot repository found in "CVS/.cvspass". */
/* Remove any entry for the CVSRoot repository found in .cvspass. */
int
logout (argc, argv)
int argc;
@ -403,7 +405,7 @@ logout (argc, argv)
{
char *passfile;
FILE *fp;
char *tmp_name;
char *tmp_name = NULL;
FILE *tmp_fp;
char *linebuf = (char *) NULL;
size_t linebuf_len;
@ -498,6 +500,10 @@ logout (argc, argv)
error (0, errno, "cannot remove %s", tmp_name);
chmod (passfile, 0600);
}
if (tmp_name)
free (tmp_name);
return 0;
}

View File

@ -182,7 +182,6 @@ do_editor (dir, messagep, repository, changes)
char *fname;
struct stat pre_stbuf, post_stbuf;
int retcode = 0;
char *p;
if (noexec || reuse_log_message)
return;
@ -216,7 +215,6 @@ do_editor (dir, messagep, repository, changes)
{
FILE *tfp;
char buf[1024];
char *p;
size_t n;
size_t nwrite;
@ -231,9 +229,9 @@ do_editor (dir, messagep, repository, changes)
{
while (!feof (tfp))
{
char *p = buf;
n = fread (buf, 1, sizeof buf, tfp);
nwrite = n;
p = buf;
while (nwrite > 0)
{
n = fwrite (p, 1, nwrite, fp);
@ -315,7 +313,8 @@ do_editor (dir, messagep, repository, changes)
if (*messagep)
{
p = *messagep;
size_t message_len = post_stbuf.st_size + 1;
size_t offset = 0;
while (1)
{
line_length = getline (&line, &line_chars_allocated, fp);
@ -327,8 +326,11 @@ do_editor (dir, messagep, repository, changes)
}
if (strncmp (line, CVSEDITPREFIX, CVSEDITPREFIXLEN) == 0)
continue;
(void) strcpy (p, line);
p += line_length;
if (offset + line_length >= message_len)
expand_string (messagep, &message_len,
offset + line_length + 1);
(void) strcpy (*messagep + offset, line);
offset += line_length;
}
}
if (fclose (fp) < 0)
@ -759,7 +761,7 @@ logfile_write (repository, filter, message, logfp, changes)
}
len = fmt_end - fmt_begin;
str_list_format = xmalloc (sizeof (char) * (len + 1));
str_list_format = xmalloc (len + 1);
strncpy (str_list_format, fmt_begin, len);
str_list_format[len] = '\0';

View File

@ -111,30 +111,31 @@ static const struct cmd
{ "history", "hi", "his", history },
{ "import", "im", "imp", import },
{ "init", NULL, NULL, init },
#ifdef SERVER_SUPPORT
#if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT)
{ "kserver", NULL, NULL, server }, /* placeholder */
#endif
{ "log", "lo", "rlog", cvslog },
#ifdef AUTH_CLIENT_SUPPORT
{ "login", "logon", "lgn", login },
{ "logout", NULL, NULL, logout },
#ifdef SERVER_SUPPORT
#endif /* AUTH_CLIENT_SUPPORT */
#if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
{ "pserver", NULL, NULL, server }, /* placeholder */
#endif
#endif /* AUTH_CLIENT_SUPPORT */
{ "rdiff", "patch", "pa", patch },
{ "release", "re", "rel", release },
{ "remove", "rm", "delete", cvsremove },
{ "status", "st", "stat", cvsstatus },
{ "rtag", "rt", "rfreeze", rtag },
{ "tag", "ta", "freeze", cvstag },
{ "unedit", NULL, NULL, unedit },
{ "update", "up", "upd", update },
{ "watch", NULL, NULL, watch },
{ "watchers", NULL, NULL, watchers },
#ifdef SERVER_SUPPORT
{ "server", NULL, NULL, server },
#endif
{ "status", "st", "stat", cvsstatus },
{ "tag", "ta", "freeze", cvstag },
{ "unedit", NULL, NULL, unedit },
{ "update", "up", "upd", update },
{ "version", "ve", "ver", version },
{ "watch", NULL, NULL, watch },
{ "watchers", NULL, NULL, watchers },
{ NULL, NULL, NULL, NULL },
};
@ -179,7 +180,7 @@ static const char *const usg[] =
version control means. */
"For CVS updates and additional information, see\n",
" Cyclic Software at http://www.cyclic.com/ or\n",
" the CVS home page at http://www.cvshome.org/ or\n",
" Pascal Molli's CVS site at http://www.loria.fr/~molli/cvs-index.html\n",
NULL,
};
@ -199,15 +200,24 @@ static const char *const cmd_usage[] =
" 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",
#if defined (HAVE_KERBEROS) && defined (SERVER_SUPPORT)
" kserver Kerberos server mode\n",
#endif
" log Print out history information for files\n",
#ifdef AUTH_CLIENT_SUPPORT
" login Prompt for password for authenticating server.\n",
" logout Removes entry in .cvspass for remote repository.\n",
" login Prompt for password for authenticating server\n",
" logout Removes entry in .cvspass for remote repository\n",
#endif /* AUTH_CLIENT_SUPPORT */
#if (defined(AUTH_SERVER_SUPPORT) || defined (HAVE_GSSAPI)) && defined(SERVER_SUPPORT)
" pserver Password server mode\n",
#endif
" rdiff Create 'patch' format diffs between releases\n",
" release Indicate that a Module is no longer in use\n",
" remove Remove an entry from the repository\n",
" rtag Add a symbolic tag to a module\n",
#ifdef SERVER_SUPPORT
" server Server mode\n",
#endif
" 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",
@ -343,6 +353,7 @@ lookup_command_attribute (cmd_name)
(strcmp (cmd_name, "log") != 0) &&
(strcmp (cmd_name, "noop") != 0) &&
(strcmp (cmd_name, "watchers") != 0) &&
(strcmp (cmd_name, "release") != 0) &&
(strcmp (cmd_name, "status") != 0))
{
ret |= CVS_CMD_MODIFIES_REPOSITORY;
@ -362,6 +373,11 @@ main_cleanup (sig)
switch (sig)
{
#ifdef SIGABRT
case SIGABRT:
name = "abort";
break;
#endif
#ifdef SIGHUP
case SIGHUP:
name = "hangup";
@ -405,8 +421,6 @@ main (argc, argv)
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;
@ -418,6 +432,7 @@ main (argc, argv)
int help = 0; /* Has the user asked for help? This
lets us support the `cvs -H cmd'
convention to give help for cmd. */
static const char short_options[] = "+Qqrwtnlvb:T:e:d:Hfz:s:xa";
static struct option long_options[] =
{
{"help", 0, NULL, 'H'},
@ -492,7 +507,7 @@ main (argc, argv)
opterr = 0;
while ((c = getopt_long
(argc, argv, "+f", NULL, NULL))
(argc, argv, short_options, long_options, &option_index))
!= EOF)
{
if (c == 'f')
@ -509,7 +524,7 @@ main (argc, argv)
opterr = 1;
while ((c = getopt_long
(argc, argv, "+Qqrwtnlvb:T:e:d:Hfz:s:xa", long_options, &option_index))
(argc, argv, short_options, long_options, &option_index))
!= EOF)
{
switch (c)
@ -551,14 +566,11 @@ main (argc, argv)
logoff = 1;
break;
case 'v':
/* Having the year here is a good idea, so people have
some idea of how long ago their version of CVS was
released. */
(void) fputs (version_string, stdout);
(void) fputs (config_string, stdout);
(void) fputs ("\n", stdout);
version (0, (char **) NULL);
(void) fputs ("\n", stdout);
(void) fputs ("\
Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
Copyright (c) 1989-2000 Brian Berliner, david d `zoo' zuhn, \n\
Jeff Polk, and other authors\n", stdout);
(void) fputs ("\n", stdout);
(void) fputs ("CVS may be copied only under the terms of the GNU General Public License,\n", stdout);
@ -602,9 +614,9 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
case 'z':
#ifdef CLIENT_SUPPORT
gzip_level = atoi (optarg);
if (gzip_level <= 0 || gzip_level > 9)
if (gzip_level < 0 || gzip_level > 9)
error (1, 0,
"gzip compression level must be between 1 and 9");
"gzip compression level must be between 0 and 9");
#endif
/* If no CLIENT_SUPPORT, we just silently ignore the gzip
level, so that users can have it in their .cvsrc and not
@ -657,7 +669,10 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
}
if (!cm->fullname)
usage (cmd_usage); /* no match */
{
fprintf (stderr, "Unknown command: `%s'\n\n", command_name);
usage (cmd_usage);
}
else
command_name = cm->fullname; /* Global pointer for later use */
@ -765,25 +780,23 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
#ifndef DONT_USE_SIGNALS
/* make sure we clean up on error */
#ifdef SIGABRT
(void) SIG_register (SIGABRT, main_cleanup);
#endif
#ifdef SIGHUP
(void) SIG_register (SIGHUP, main_cleanup);
(void) SIG_register (SIGHUP, Lock_Cleanup);
#endif
#ifdef SIGINT
(void) SIG_register (SIGINT, main_cleanup);
(void) SIG_register (SIGINT, Lock_Cleanup);
#endif
#ifdef SIGQUIT
(void) SIG_register (SIGQUIT, main_cleanup);
(void) SIG_register (SIGQUIT, Lock_Cleanup);
#endif
#ifdef SIGPIPE
(void) SIG_register (SIGPIPE, main_cleanup);
(void) SIG_register (SIGPIPE, Lock_Cleanup);
#endif
#ifdef SIGTERM
(void) SIG_register (SIGTERM, main_cleanup);
(void) SIG_register (SIGTERM, Lock_Cleanup);
#endif
#endif /* !DONT_USE_SIGNALS */
@ -878,7 +891,7 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
{
Node *n;
n = getnode ();
n->type = UNKNOWN;
n->type = NT_UNKNOWN;
n->key = xstrdup (CVSroot);
n->data = NULL;
@ -921,11 +934,8 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
current_root);
/*
* 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.
* Check to see if the repository exists.
*/
if (!client_active)
{
char *path;
@ -933,8 +943,7 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
path = xmalloc (strlen (CVSroot_directory)
+ sizeof (CVSROOTADM)
+ 20
+ sizeof (CVSROOTADM_HISTORY));
+ 20);
(void) sprintf (path, "%s/%s", CVSroot_directory, CVSROOTADM);
if (!isaccessible (path, R_OK | X_OK))
{
@ -945,14 +954,6 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
error (1, save_errno, "%s", path);
}
}
(void) strcat (path, "/");
(void) strcat (path, CVSROOTADM_HISTORY);
if (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);
}
free (path);
}
@ -961,12 +962,17 @@ Copyright (c) 1989-1998 Brian Berliner, david d `zoo' zuhn, \n\
/* FIXME (njc): should we always set this with the CVSROOT from the command line? */
if (cvs_update_env)
{
static char *prev;
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 */
/* do not free env yet, as putenv has control of it */
/* but do free the previous value, if any */
if (prev != NULL)
free (prev);
prev = env;
}
#endif
}

View File

@ -280,14 +280,23 @@ static const char *const config_contents[] = {
"# Set this to \"no\" if pserver shouldn't check system users/passwords\n",
"#SystemAuth=no\n",
"\n",
"# Put CVS lock files in this directory rather than directly in the repository.\n",
"#LockDir=/var/lock/cvs\n",
"\n",
#ifdef PRESERVE_PERMISSIONS_SUPPORT
"# Set `PreservePermissions' to `yes' to save file status information\n",
"# in the repository.\n",
"#PreservePermissions=no\n",
"\n",
#endif
"# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top\n",
"# level of the new working directory when using the `cvs checkout'\n",
"# command.\n",
"#TopLevelAdmin=no\n",
"\n",
"# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the\n",
"# history file, or a subset as needed (ie `TMAR' logs all write operations)\n",
"#LogHistory=TOFEWGCMAR\n",
NULL
};
@ -372,6 +381,9 @@ mkmodules (dir)
size_t line_allocated = 0;
const struct admin_file *fileptr;
if (noexec)
return 0;
if (save_cwd (&cwd))
error_exit ();
@ -865,6 +877,9 @@ init (argc, argv)
if ( CVS_CHDIR (adm) < 0)
error (1, errno, "cannot change to directory %s", adm);
/* Make Emptydir so it's there if we need it */
mkdir_if_needed (CVSNULLREPOS);
/* 80 is long enough for all the administrative file names, plus
"/" and so on. */
info = xmalloc (strlen (adm) + 80);
@ -926,6 +941,29 @@ init (argc, argv)
fp = open_file (info, "w");
if (fclose (fp) < 0)
error (1, errno, "cannot close %s", info);
/* Make the new history file world-writeable, since every CVS
user will need to be able to write to it. We use chmod()
because xchmod() is too shy. */
chmod (info, 0666);
}
/* Make an empty val-tags file to prevent problems creating it later. */
strcpy (info, adm);
strcat (info, "/");
strcat (info, CVSROOTADM_VALTAGS);
if (!isfile (info))
{
FILE *fp;
fp = open_file (info, "w");
if (fclose (fp) < 0)
error (1, errno, "cannot close %s", info);
/* Make the new val-tags file world-writeable, since every CVS
user will need to be able to write to it. We use chmod()
because xchmod() is too shy. */
chmod (info, 0666);
}
free (info);

View File

@ -120,10 +120,9 @@ do_module (db, mname, m_type, msg, callback_proc, where,
int modargc;
int xmodargc;
char **modargv;
char **xmodargv;
char **xmodargv = NULL;
/* Found entry from modules file, including options and such. */
char *value = NULL;
char *zvalue = NULL;
char *mwhere = NULL;
char *mfile = NULL;
char *spec_opt = NULL;
@ -186,25 +185,21 @@ do_module (db, mname, m_type, msg, callback_proc, where,
val.dptr = NULL;
if (val.dptr != NULL)
{
/* null terminate the value XXX - is this space ours? */
val.dptr[val.dsize] = '\0';
/* copy and null terminate the value */
value = xmalloc (val.dsize + 1);
memcpy (value, val.dptr, val.dsize);
value[val.dsize] = '\0';
/* If the line ends in a comment, strip it off */
if ((cp = strchr (val.dptr, '#')) != NULL)
{
do
*cp-- = '\0';
while (isspace ((unsigned char) *cp));
}
if ((cp = strchr (value, '#')) != NULL)
*cp = '\0';
else
{
/* Always strip trailing spaces */
cp = strchr (val.dptr, '\0');
while (cp > val.dptr && isspace ((unsigned char) *--cp))
*cp = '\0';
}
cp = value + val.dsize;
/* Always strip trailing spaces */
while (cp > value && isspace ((unsigned char) *--cp))
*cp = '\0';
value = val.dptr;
mwhere = xstrdup (mname);
goto found;
}
@ -297,7 +292,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
error_exit ();
cwd_saved = 1;
err += callback_proc (&modargc, modargv, where, mwhere, mfile,
err += callback_proc (modargc, modargv, where, mwhere, mfile,
shorten,
local_specified, mname, msg);
@ -332,17 +327,20 @@ do_module (db, mname, m_type, msg, callback_proc, where,
{
char *cp2;
/* null terminate the value XXX - is this space ours? */
val.dptr[val.dsize] = '\0';
/* copy and null terminate the value */
value = xmalloc (val.dsize + 1);
memcpy (value, val.dptr, val.dsize);
value[val.dsize] = '\0';
/* If the line ends in a comment, strip it off */
if ((cp2 = strchr (val.dptr, '#')) != NULL)
{
do
*cp2-- = '\0';
while (isspace ((unsigned char) *cp2));
}
value = val.dptr;
if ((cp2 = strchr (value, '#')) != NULL)
*cp2 = '\0';
else
cp2 = value + val.dsize;
/* Always strip trailing spaces */
while (cp2 > value && isspace ((unsigned char) *--cp2))
*cp2 = '\0';
/* mwhere gets just the module name */
mwhere = xstrdup (mname);
@ -375,11 +373,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
error_exit ();
cwd_saved = 1;
/* copy value to our own string since if we go recursive we'll be
really screwed if we do another dbm lookup */
assert (value != NULL);
zvalue = xstrdup (value);
value = zvalue;
/* search the value for the special delimiter and save for later */
if ((cp = strchr (value, CVSMODULE_SPEC)) != NULL)
@ -387,62 +381,9 @@ do_module (db, mname, m_type, msg, callback_proc, where,
*cp = '\0'; /* null out the special char */
spec_opt = cp + 1; /* save the options for later */
if (cp != value) /* strip whitespace if necessary */
while (isspace ((unsigned char) *--cp))
*cp = '\0';
if (cp == value)
{
/*
* we had nothing but special options, so skip arg
* parsing and regular stuff entirely
*
* If there were only special ones though, we must
* make the appropriate directory and cd to it
*/
char *dir;
/* XXX - XXX - MAJOR HACK - DO NOT SHIP - this needs to
be !pipeout, but we don't know that here yet */
if (!run_module_prog)
goto out;
dir = where ? where : mname;
/* XXX - think about making null repositories at each dir here
instead of just at the bottom */
make_directories (dir);
if ( CVS_CHDIR (dir) < 0)
{
error (0, errno, "cannot chdir to %s", dir);
spec_opt = NULL;
err++;
goto out;
}
if (!isfile (CVSADM))
{
char *nullrepos;
nullrepos = emptydir_name ();
Create_Admin (".", dir,
nullrepos, (char *) NULL, (char *) NULL, 0, 0);
if (!noexec)
{
FILE *fp;
fp = open_file (CVSADM_ENTSTAT, "w+");
if (fclose (fp) == EOF)
error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
#ifdef SERVER_SUPPORT
if (server_active)
server_set_entstat (dir, nullrepos);
#endif
}
free (nullrepos);
}
out:
goto do_special;
}
/* strip whitespace if necessary */
while (cp > value && isspace ((unsigned char) *--cp))
*cp = '\0';
}
/* don't do special options only part of a module was specified */
@ -460,7 +401,8 @@ do_module (db, mname, m_type, msg, callback_proc, where,
/* Put the value on a line with XXX prepended for getopt to eat */
line = xmalloc (strlen (value) + 10);
(void) sprintf (line, "%s %s", "XXX", value);
strcpy(line, "XXX ");
strcpy(line + 4, value);
/* turn the line into an argv[] array */
line2argv (&xmodargc, &xmodargv, line, " \t");
@ -478,56 +420,56 @@ do_module (db, mname, m_type, msg, callback_proc, where,
alias = 1;
break;
case 'd':
nonalias_opt = 1;
if (mwhere)
free (mwhere);
mwhere = xstrdup (optarg);
nonalias_opt = 1;
break;
case 'i':
nonalias_opt = 1;
if (checkin_prog)
free (checkin_prog);
checkin_prog = xstrdup (optarg);
nonalias_opt = 1;
break;
case 'l':
nonalias_opt = 1;
local_specified = 1;
nonalias_opt = 1;
break;
case 'o':
nonalias_opt = 1;
if (checkout_prog)
free (checkout_prog);
checkout_prog = xstrdup (optarg);
nonalias_opt = 1;
break;
case 'e':
nonalias_opt = 1;
if (export_prog)
free (export_prog);
export_prog = xstrdup (optarg);
nonalias_opt = 1;
break;
case 't':
nonalias_opt = 1;
if (tag_prog)
free (tag_prog);
tag_prog = xstrdup (optarg);
nonalias_opt = 1;
break;
case 'u':
nonalias_opt = 1;
if (update_prog)
free (update_prog);
update_prog = xstrdup (optarg);
nonalias_opt = 1;
break;
case '?':
error (0, 0,
"modules file has invalid option for key %s value %s",
key.dptr, val.dptr);
key.dptr, value);
err++;
goto do_module_return;
}
}
modargc -= optind;
modargv += optind;
if (modargc == 0)
if (modargc == 0 && spec_opt == NULL)
{
error (0, 0, "modules file missing directory for module %s", mname);
++err;
@ -575,15 +517,66 @@ module `%s' is a request for a file in a module which is not a directory",
}
/* otherwise, process this module */
err += callback_proc (&modargc, modargv, where, mwhere, mfile, shorten,
local_specified, mname, msg);
if (modargc > 0)
{
err += callback_proc (modargc, modargv, where, mwhere, mfile, shorten,
local_specified, mname, msg);
}
else
{
/*
* we had nothing but special options, so we must
* make the appropriate directory and cd to it
*/
char *dir;
free_names (&xmodargc, xmodargv);
/* XXX - XXX - MAJOR HACK - DO NOT SHIP - this needs to
be !pipeout, but we don't know that here yet */
if (!run_module_prog)
goto do_special;
dir = where ? where : (mwhere ? mwhere : mname);
/* XXX - think about making null repositories at each dir here
instead of just at the bottom */
make_directories (dir);
if ( CVS_CHDIR (dir) < 0)
{
error (0, errno, "cannot chdir to %s", dir);
spec_opt = NULL;
err++;
goto do_special;
}
if (!isfile (CVSADM))
{
char *nullrepos;
nullrepos = emptydir_name ();
Create_Admin (".", dir,
nullrepos, (char *) NULL, (char *) NULL, 0, 0, 1);
if (!noexec)
{
FILE *fp;
fp = open_file (CVSADM_ENTSTAT, "w+");
if (fclose (fp) == EOF)
error (1, errno, "cannot close %s", CVSADM_ENTSTAT);
#ifdef SERVER_SUPPORT
if (server_active)
server_set_entstat (dir, nullrepos);
#endif
}
free (nullrepos);
}
}
/* if there were special include args, process them now */
do_special:
free_names (&xmodargc, xmodargv);
xmodargv = NULL;
/* blow off special options if -l was specified */
if (local_specified)
spec_opt = NULL;
@ -635,7 +628,7 @@ module `%s' is a request for a file in a module which is not a directory",
/* strip whitespace off the end */
do
*cp = '\0';
while (isspace ((unsigned char) *--cp));
while (cp > spec_opt && isspace ((unsigned char) *--cp));
}
else
next_opt = NULL;
@ -745,6 +738,7 @@ module `%s' is a request for a file in a module which is not a directory",
cvs_output (": Executing '", 0);
run_print (stdout);
cvs_output ("'\n", 0);
cvs_flushout ();
}
err += run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
free (expanded_path);
@ -755,6 +749,8 @@ module `%s' is a request for a file in a module which is not a directory",
do_module_return:
/* clean up */
if (xmodargv != NULL)
free_names (&xmodargc, xmodargv);
if (mwhere)
free (mwhere);
if (checkin_prog)
@ -769,8 +765,8 @@ module `%s' is a request for a file in a module which is not a directory",
free (update_prog);
if (cwd_saved)
free_cwd (&cwd);
if (zvalue != NULL)
free (zvalue);
if (value != NULL)
free (value);
if (xvalue != NULL)
free (xvalue);

View File

@ -211,7 +211,8 @@ mydbm_load_file (fp, list)
value = xmalloc (value_allocated);
cont = 0;
while ((line_length = getstr (&line, &line_size, fp, '\012', 0)) >= 0)
while ((line_length =
getstr (&line, &line_size, fp, '\012', 0, GETLINE_NO_LIMIT)) >= 0)
{
if (line_length > 0 && line[line_length - 1] == '\012')
{

View File

@ -10,6 +10,8 @@
#include "getline.h"
#include <assert.h>
extern char *logHistory;
/*
* Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for
* the first line in the file that matches the REPOSITORY, or if ALL != 0, any lines
@ -32,7 +34,7 @@ Parse_Info (infofile, repository, callproc, all)
char *default_value = NULL;
char *expanded_value= NULL;
int callback_done, line_number;
char *cp, *exp, *value, *srepos;
char *cp, *exp, *value, *srepos, bad;
const char *regex_err;
if (CVSroot_original == NULL)
@ -110,10 +112,6 @@ Parse_Info (infofile, repository, callproc, all)
if (expanded_value != NULL)
free (expanded_value);
expanded_value = expand_path (value, infofile, line_number);
if (!expanded_value)
{
continue;
}
/*
* At this point, exp points to the regular expression, and value
@ -127,9 +125,10 @@ Parse_Info (infofile, repository, callproc, all)
{
/* Is it OK to silently ignore all but the last DEFAULT
expression? */
if (default_value != NULL)
if (default_value != NULL && default_value != &bad)
free (default_value);
default_value = xstrdup (expanded_value);
default_value = (expanded_value != NULL ?
xstrdup (expanded_value) : &bad);
continue;
}
@ -140,11 +139,13 @@ Parse_Info (infofile, repository, callproc, all)
*/
if (strcmp (exp, "ALL") == 0)
{
if (all)
err += callproc (repository, expanded_value);
else
if (!all)
error(0, 0, "Keyword `ALL' is ignored at line %d in %s file",
line_number, infofile);
else if (expanded_value != NULL)
err += callproc (repository, expanded_value);
else
err++;
continue;
}
@ -163,7 +164,10 @@ Parse_Info (infofile, repository, callproc, all)
continue; /* no match */
/* it did, so do the callback and note that we did one */
err += callproc (repository, expanded_value);
if (expanded_value != NULL)
err += callproc (repository, expanded_value);
else
err++;
callback_done = 1;
}
if (ferror (fp_info))
@ -173,10 +177,15 @@ Parse_Info (infofile, repository, callproc, all)
/* if we fell through and didn't callback at all, do the default */
if (callback_done == 0 && default_value != NULL)
err += callproc (repository, default_value);
{
if (default_value != &bad)
err += callproc (repository, default_value);
else
err++;
}
/* free up space if necessary */
if (default_value != NULL)
if (default_value != NULL && default_value != &bad)
free (default_value);
if (expanded_value != NULL)
free (expanded_value);
@ -367,6 +376,14 @@ warning: this CVS does not support PreservePermissions");
opendir it or something, but I don't see any particular
reason to do that now rather than waiting until lock.c. */
}
else if (strcmp (line, "LogHistory") == 0)
{
if (strcmp (p, "all") != 0)
{
logHistory=malloc(strlen (p) + 1);
strcpy (logHistory, p);
}
}
else
{
/* We may be dealing with a keyword which was added in a

View File

@ -20,7 +20,7 @@ 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,
static int patch_proc PROTO((int argc, char **argv, char *xwhere,
char *mwhere, char *mfile, int shorten,
int local_specified, char *mname, char *msg));
@ -230,6 +230,9 @@ patch (argc, argv)
#endif
/* clean up if we get a signal */
#ifdef SIGABRT
(void) SIG_register (SIGABRT, patch_cleanup);
#endif
#ifdef SIGHUP
(void) SIG_register (SIGHUP, patch_cleanup);
#endif
@ -261,9 +264,9 @@ patch (argc, argv)
*/
/* ARGSUSED */
static int
patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
patch_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
mname, msg)
int *pargc;
int argc;
char **argv;
char *xwhere;
char *mwhere;
@ -273,6 +276,7 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
char *mname;
char *msg;
{
char *myargv[2];
int err = 0;
int which;
char *repository;
@ -314,13 +318,10 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
}
else
{
int i;
/* a file means muck argv */
for (i = 1; i < *pargc; i++)
free (argv[i]);
argv[1] = xstrdup (mfile);
(*pargc) = 2;
myargv[0] = argv[0];
myargv[1] = mfile;
argc = 2;
argv = myargv;
}
free (path);
}
@ -341,19 +342,19 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
if (rev1 != NULL && !rev1_validated)
{
tag_check_valid (rev1, *pargc - 1, argv + 1, local, 0, NULL);
tag_check_valid (rev1, argc - 1, argv + 1, local, 0, NULL);
rev1_validated = 1;
}
if (rev2 != NULL && !rev2_validated)
{
tag_check_valid (rev2, *pargc - 1, argv + 1, local, 0, NULL);
tag_check_valid (rev2, argc - 1, argv + 1, local, 0, NULL);
rev2_validated = 1;
}
/* start the recursion processor */
err = start_recursion (patch_fileproc, (FILESDONEPROC) NULL, patch_dirproc,
(DIRLEAVEPROC) NULL, NULL,
*pargc - 1, argv + 1, local,
argc - 1, argv + 1, local,
which, 0, 1, where, 1);
free (where);
@ -735,6 +736,10 @@ failed to read diff file header %s for %s: end of file", tmpfile3, rcs);
tmpfile1 = tmpfile2 = tmpfile3 = NULL;
out2:
if (vers_tag != NULL)
free (vers_tag);
if (vers_head != NULL)
free (vers_head);
if (rcs != NULL)
free (rcs);
return (ret);

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,10 @@
* RCS source control definitions needed by rcs.c and friends
*/
/* String which indicates a conflict if it occurs at the start of a line. */
#define RCS_MERGE_PAT ">>>>>>> "
/* Strings which indicate a conflict if they occur at the start of a line. */
#define RCS_MERGE_PAT_1 "<<<<<<< "
#define RCS_MERGE_PAT_2 "=======\n"
#define RCS_MERGE_PAT_3 ">>>>>>> "
#define RCSEXT ",v"
#define RCSPAT "*,v"
@ -227,7 +229,9 @@ int RCS_delete_revs PROTO ((RCSNode *, char *, char *, int));
void RCS_addaccess PROTO ((RCSNode *, char *));
void RCS_delaccess PROTO ((RCSNode *, char *));
char *RCS_getaccess PROTO ((RCSNode *));
RETSIGTYPE rcs_cleanup PROTO ((void));
void RCS_rewrite PROTO ((RCSNode *, Deltatext *, char *));
void RCS_abandon PROTO ((RCSNode *));
int rcs_change_text PROTO ((const char *, char *, size_t, const char *,
size_t, char **, size_t *));
char *make_file_label PROTO ((char *, char *, RCSNode *));

View File

@ -173,6 +173,7 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc, callerdat,
seems to be handled somewhere (else) but why should
it be a separate case? Needs investigation... */
just_subdirs = 1;
free (root);
}
#endif
@ -590,7 +591,7 @@ do_recursion (frame)
/* Add it to our list. */
Node *n = getnode ();
n->type = UNKNOWN;
n->type = NT_UNKNOWN;
n->key = xstrdup (this_root);
if (addnode (root_directories, n))
@ -1015,7 +1016,7 @@ but CVS uses %s for its own purposes; skipping %s directory",
/* Add it to our list. */
Node *n = getnode ();
n->type = UNKNOWN;
n->type = NT_UNKNOWN;
n->key = xstrdup (this_root);
if (addnode (root_directories, n))
@ -1132,6 +1133,7 @@ addfile (listp, dir, file)
char *file;
{
Node *n;
List *fl;
/* add this dir. */
addlist (listp, dir);
@ -1144,7 +1146,9 @@ addfile (listp, dir, file)
}
n->type = DIRS;
addlist ((List **) &n->data, file);
fl = (List *) n->data;
addlist (&fl, file);
n->data = (char *) fl;
return;
}
@ -1204,6 +1208,7 @@ unroll_files_proc (p, closure)
}
dirlist = save_dirlist;
filelist = NULL;
if (filelist)
dellist (&filelist);
return(err);
}

View File

@ -190,7 +190,7 @@ release (argc, argv)
{
if (strchr ("MARCZ", *line))
c++;
(void) printf (line);
(void) fputs (line, stdout);
}
if (line_length < 0 && !feof (fp))
error (0, errno, "cannot read from subprocess");

View File

@ -103,6 +103,7 @@ cvsremove (argc, argv)
/* FIXME: Can't we set SEND_NO_CONTENTS here? Needs investigation. */
send_files (argc, argv, local, 0, 0);
send_file_names (argc, argv, 0);
free_names (&argc, argv);
send_to_server ("remove\012", 0);
return get_responses_and_close ();
}

View File

@ -106,12 +106,6 @@ Name_Repository (dir, update_dir)
* one by tacking on the CVSROOT environment variable. If the CVSROOT
* environment variable is not set, die now.
*/
if (strcmp (repos, "..") == 0 || strncmp (repos, "../", 3) == 0)
{
error (0, 0, "in directory %s:", xupdate_dir);
error (0, 0, "`..'-relative repositories are not supported.");
error (1, 0, "illegal source repository");
}
if (! isabsolute(repos))
{
char *newrepos;
@ -123,6 +117,12 @@ Name_Repository (dir, update_dir)
error (0, 0, "or specify the '-d' option to %s.", program_name);
error (1, 0, "illegal repository setting");
}
if (pathname_levels (repos) > 0)
{
error (0, 0, "in directory %s:", xupdate_dir);
error (0, 0, "`..'-relative repositories are not supported.");
error (1, 0, "illegal source repository");
}
newrepos = xmalloc (strlen (CVSroot_directory) + strlen (repos) + 10);
(void) sprintf (newrepos, "%s/%s", CVSroot_directory, repos);
free (repos);

View File

@ -174,9 +174,9 @@ Create_Root (dir, rootdir)
directories. Then we can check against them when a remote user
hands us a CVSROOT directory. */
static unsigned int root_allow_count;
static int root_allow_count;
static char **root_allow_vector;
static unsigned int root_allow_size;
static int root_allow_size;
void
root_allow_add (arg)
@ -233,8 +233,7 @@ void
root_allow_free ()
{
if (root_allow_vector != NULL)
free (root_allow_vector);
root_allow_count = 0;
free_names (&root_allow_count, root_allow_vector);
root_allow_size = 0;
}
@ -242,7 +241,7 @@ int
root_allow_ok (arg)
char *arg;
{
unsigned int i;
int i;
if (root_allow_count == 0)
{
@ -295,7 +294,7 @@ parse_cvsroot (CVSroot)
char *CVSroot;
{
static int cvsroot_parsed = 0;
char *cvsroot_copy, *p;
char *cvsroot_copy, *cvsroot_save, *p;
int check_hostname;
/* Don't go through the trouble twice. */
@ -305,10 +304,19 @@ parse_cvsroot (CVSroot)
return 0;
}
CVSroot_original = xstrdup (CVSroot);
cvsroot_copy = xstrdup (CVSroot);
if (CVSroot_original != NULL)
free (CVSroot_original);
if (CVSroot_directory != NULL)
free (CVSroot_directory);
if (CVSroot_username != NULL)
free (CVSroot_username);
if (CVSroot_hostname != NULL)
free (CVSroot_hostname);
if ((*cvsroot_copy == ':'))
CVSroot_original = xstrdup (CVSroot);
cvsroot_save = cvsroot_copy = xstrdup (CVSroot);
if (*cvsroot_copy == ':')
{
char *method = ++cvsroot_copy;
@ -324,6 +332,7 @@ parse_cvsroot (CVSroot)
if (! (p = strchr (method, ':')))
{
error (0, 0, "bad CVSroot: %s", CVSroot);
free (cvsroot_save);
return 1;
}
*p = '\0';
@ -348,6 +357,7 @@ parse_cvsroot (CVSroot)
else
{
error (0, 0, "unknown method in CVSroot: %s", CVSroot);
free (cvsroot_save);
return 1;
}
}
@ -378,19 +388,19 @@ parse_cvsroot (CVSroot)
{
/* Check to see if there is a username in the string. */
if ((p = strchr (cvsroot_copy, '@')))
if ((p = strchr (cvsroot_copy, '@')) != NULL)
{
CVSroot_username = cvsroot_copy;
*p = '\0';
CVSroot_username = xstrdup (cvsroot_copy);
cvsroot_copy = ++p;
if (*CVSroot_username == '\0')
CVSroot_username = NULL;
}
if ((p = strchr (cvsroot_copy, ':')))
if ((p = strchr (cvsroot_copy, ':')) != NULL)
{
CVSroot_hostname = cvsroot_copy;
*p = '\0';
CVSroot_hostname = xstrdup (cvsroot_copy);
cvsroot_copy = ++p;
if (*CVSroot_hostname == '\0')
@ -398,7 +408,8 @@ parse_cvsroot (CVSroot)
}
}
CVSroot_directory = cvsroot_copy;
CVSroot_directory = xstrdup(cvsroot_copy);
free (cvsroot_save);
#if ! defined (CLIENT_SUPPORT) && ! defined (DEBUG)
if (CVSroot_method != local_method)
@ -422,12 +433,10 @@ parse_cvsroot (CVSroot)
switch (CVSroot_method)
{
case local_method:
case fork_method:
if (CVSroot_username || CVSroot_hostname)
{
error (0, 0, "can't specify hostname and username in CVSROOT");
error (0, 0, "when using %s access method",
CVSroot_method == local_method ? "local" : "fork");
error (0, 0, "when using local access method");
error (0, 0, "(%s)", CVSroot);
return 1;
}
@ -440,6 +449,18 @@ parse_cvsroot (CVSroot)
error (1, 0, "CVSROOT %s must be an absolute pathname",
CVSroot_directory);
break;
case fork_method:
/* We want :fork: to behave the same as other remote access
methods. Therefore, don't check to see that the repository
name is absolute -- let the server do it. */
if (CVSroot_username || CVSroot_hostname)
{
error (0, 0, "can't specify hostname and username in CVSROOT");
error (0, 0, "when using fork access method");
error (0, 0, "(%s)", CVSroot);
return 1;
}
break;
case kserver_method:
#ifndef HAVE_KERBEROS
error (0, 0, "Your CVSROOT is set for a kerberos access method");
@ -488,18 +509,24 @@ parse_cvsroot (CVSroot)
/* Set up the global CVSroot* variables as if we're using the local
repository DIR. DIR must point to storage which will last for the
rest of the CVS invocation (for example, the caller might malloc it
and never free it, or free it just before exiting CVS). */
repository DIR. */
void
set_local_cvsroot (dir)
char *dir;
{
CVSroot_original = dir;
if (CVSroot_original != NULL)
free (CVSroot_original);
CVSroot_original = xstrdup(dir);
CVSroot_method = local_method;
CVSroot_directory = CVSroot_original;
if (CVSroot_directory != NULL)
free (CVSroot_directory);
CVSroot_directory = xstrdup(dir);
if (CVSroot_username != NULL)
free (CVSroot_username);
CVSroot_username = NULL;
if (CVSroot_hostname != NULL)
free (CVSroot_hostname);
CVSroot_hostname = NULL;
client_active = 0;
}

View File

@ -29,7 +29,7 @@ static int rtag_fileproc PROTO ((void *callerdat, struct file_info *finfo));
static int rtag_filesdoneproc PROTO ((void *callerdat, int err,
char *repos, char *update_dir,
List *entries));
static int rtag_proc PROTO((int *pargc, char **argv, char *xwhere,
static int rtag_proc PROTO((int argc, char **argv, char *xwhere,
char *mwhere, char *mfile, int shorten,
int local_specified, char *mname, char *msg));
static int rtag_delete PROTO((RCSNode *rcsfile));
@ -222,9 +222,9 @@ rtag (argc, argv)
*/
/* ARGSUSED */
static int
rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
rtag_proc (argc, argv, xwhere, mwhere, mfile, shorten, local_specified,
mname, msg)
int *pargc;
int argc;
char **argv;
char *xwhere;
char *mwhere;
@ -236,6 +236,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
{
/* Begin section which is identical to patch_proc--should this
be abstracted out somehow? */
char *myargv[2];
int err = 0;
int which;
char *repository;
@ -277,13 +278,10 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
}
else
{
int i;
/* a file means muck argv */
for (i = 1; i < *pargc; i++)
free (argv[i]);
argv[1] = xstrdup (mfile);
(*pargc) = 2;
myargv[0] = argv[0];
myargv[1] = mfile;
argc = 2;
argv = myargv;
}
free (path);
}
@ -305,7 +303,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
if (numtag != NULL && !numtag_validated)
{
tag_check_valid (numtag, *pargc - 1, argv + 1, local, 0, NULL);
tag_check_valid (numtag, argc - 1, argv + 1, local, 0, NULL);
numtag_validated = 1;
}
@ -315,7 +313,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
mtlist = getlist();
err = start_recursion (check_fileproc, check_filesdoneproc,
(DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL,
*pargc - 1, argv + 1, local, which, 0, 1,
argc - 1, argv + 1, local, which, 0, 1,
where, 1);
if (err)
@ -326,7 +324,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
/* start the recursion processor */
err = start_recursion (rtag_fileproc, rtag_filesdoneproc, rtag_dirproc,
(DIRLEAVEPROC) NULL, NULL,
*pargc - 1, argv + 1, local,
argc - 1, argv + 1, local,
which, 0, 0, where, 1);
free (where);
dellist(&mtlist);

View File

@ -207,6 +207,18 @@ run_exec (stin, stout, sterr, flags)
(void) close (sherr);
}
#ifdef SETXID_SUPPORT
/*
** This prevents a user from creating a privileged shell
** from the text editor when the SETXID_SUPPORT option is selected.
*/
if (!strcmp (run_argv[0], Editor) && setegid (getgid ()))
{
error (0, errno, "cannot set egid to gid");
_exit (127);
}
#endif
/* dup'ing is done. try to run it now */
(void) execvp (run_argv[0], run_argv);
error (0, errno, "cannot exec %s", run_argv[0]);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -171,7 +171,8 @@ pathname_levels (path)
if (-level > max_level)
max_level = -level;
}
else if (p[0] == '.' && (p[1] == '\0' || p[1] == '/'))
else if (p[0] == '\0' || p[0] == '/' ||
(p[0] == '.' && (p[1] == '\0' || p[1] == '/')))
;
else
++level;
@ -218,9 +219,7 @@ line2argv (pargc, argv, line, sepchars)
int argv_allocated;
/* Small for testing. */
/* argv_allocated must be at least 3 because at some places
(e.g. checkout_proc) cvs alters argv[2]. */
argv_allocated = 4;
argv_allocated = 1;
*argv = (char **) xmalloc (argv_allocated * sizeof (**argv));
*pargc = 0;
@ -586,7 +585,9 @@ file_has_markers (finfo)
error (1, errno, "cannot open %s", finfo->fullname);
while (getline (&line, &line_allocated, fp) > 0)
{
if (strncmp (line, RCS_MERGE_PAT, sizeof RCS_MERGE_PAT - 1) == 0)
if (strncmp (line, RCS_MERGE_PAT_1, sizeof RCS_MERGE_PAT_1 - 1) == 0 ||
strncmp (line, RCS_MERGE_PAT_2, sizeof RCS_MERGE_PAT_2 - 1) == 0 ||
strncmp (line, RCS_MERGE_PAT_3, sizeof RCS_MERGE_PAT_3 - 1) == 0)
{
result = 1;
goto out;
@ -647,9 +648,9 @@ get_file (name, fullname, mode, buf, bufsize, len)
e = open_file (name, mode);
}
if (*bufsize < filesize)
if (*buf == NULL || *bufsize <= filesize)
{
*bufsize = filesize;
*bufsize = filesize + 1;
*buf = xrealloc (*buf, *bufsize);
}
@ -691,12 +692,9 @@ get_file (name, fullname, mode, buf, bufsize, len)
*len = nread;
/* Force *BUF to be large enough to hold a null terminator. */
if (*buf != NULL)
{
if (nread == *bufsize)
expand_string (buf, bufsize, *bufsize + 1);
(*buf)[nread] = '\0';
}
if (nread == *bufsize)
expand_string (buf, bufsize, *bufsize + 1);
(*buf)[nread] = '\0';
}
@ -744,3 +742,37 @@ resolve_symlink (filename)
}
}
}
/*
* Rename a file to an appropriate backup name based on BAKPREFIX.
* If suffix non-null, then ".<suffix>" is appended to the new name.
*
* Returns the new name, which caller may free() if desired.
*/
char *
backup_file (filename, suffix)
const char *filename;
const char *suffix;
{
char *backup_name;
if (suffix == NULL)
{
backup_name = xmalloc (sizeof (BAKPREFIX) + strlen (filename) + 1);
sprintf (backup_name, "%s%s", BAKPREFIX, filename);
}
else
{
backup_name = xmalloc (sizeof (BAKPREFIX)
+ strlen (filename)
+ strlen (suffix)
+ 2); /* one for dot, one for trailing '\0' */
sprintf (backup_name, "%s%s.%s", BAKPREFIX, filename, suffix);
}
if (isfile (filename))
copy_file (filename, backup_name);
return backup_name;
}

View File

@ -234,9 +234,12 @@ check_fileproc (callerdat, finfo)
if ((status != T_UPTODATE) && (status != T_CHECKOUT))
{
error (0, 0, "%s is locally modified", finfo->fullname);
freevers_ts (&vers);
return (1);
}
}
else
vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
if (finfo->update_dir[0] == '\0')
xdir = ".";
@ -266,11 +269,12 @@ check_fileproc (callerdat, finfo)
p->key = xstrdup (finfo->file);
p->type = UPDATE;
p->delproc = tag_delproc;
vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
if (vers->srcfile == NULL)
{
if (!really_quiet)
error (0, 0, "nothing known about %s", finfo->file);
freevers_ts (&vers);
freenode (p);
return (1);
}
@ -579,6 +583,8 @@ tag_fileproc (callerdat, finfo)
if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch)
{
free (oversion);
if (branch_mode)
free (rev);
freevers_ts (&vers);
return (0);
}
@ -600,6 +606,8 @@ tag_fileproc (callerdat, finfo)
cvs_output (rev, 0);
cvs_output ("\n", 1);
free (oversion);
if (branch_mode)
free (rev);
freevers_ts (&vers);
return (0);
}
@ -611,9 +619,13 @@ tag_fileproc (callerdat, finfo)
error (1, retcode == -1 ? errno : 0,
"failed to set tag %s to revision %s in %s",
symtag, rev, vers->srcfile->path);
if (branch_mode)
free (rev);
freevers_ts (&vers);
return (1);
}
if (branch_mode)
free (rev);
RCS_rewrite (vers->srcfile, NULL, NULL);
/* more warm fuzzies */
@ -718,7 +730,7 @@ val_direntproc (callerdat, dir, repository, update_dir, entries)
files in a directory which does not exist yet, but which is
about to be created. */
if (isdir (dir))
return 0;
return R_PROCESS;
return R_SKIP_ALL;
}

View File

@ -94,6 +94,7 @@ static char *tag_update_dir;
static char *join_rev1, *date_rev1;
static char *join_rev2, *date_rev2;
static int aflag = 0;
static int toss_local_changes = 0;
static int force_tag_match = 1;
static int update_build_dirs = 0;
static int update_prune_dirs = 0;
@ -110,6 +111,7 @@ static const char *const update_usage[] =
" [-I ign] [-W spec] [files...]\n",
"\t-A\tReset any sticky tags/date/kopts.\n",
"\t-P\tPrune empty directories.\n",
"\t-C\tOverwrite locally modified files with clean repository copies.\n",
"\t-d\tBuild directories, like checkout does.\n",
"\t-f\tForce a head revision match if tag/date not found.\n",
"\t-l\tLocal directory only, no recursion.\n",
@ -145,13 +147,16 @@ update (argc, argv)
/* parse the args */
optind = 0;
while ((c = getopt (argc, argv, "+ApPflRQqduk:r:D:j:I:W:")) != -1)
while ((c = getopt (argc, argv, "+ApCPflRQqduk:r:D:j:I:W:")) != -1)
{
switch (c)
{
case 'A':
aflag = 1;
break;
case 'C':
toss_local_changes = 1;
break;
case 'I':
ign_add (optarg, 0);
break;
@ -252,6 +257,8 @@ update (argc, argv)
send_arg("-f");
if (aflag)
send_arg("-A");
if (toss_local_changes)
send_arg("-C");
if (update_prune_dirs)
send_arg("-P");
client_prune_dirs = update_prune_dirs;
@ -266,28 +273,35 @@ update (argc, argv)
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.
We don't send -u if failed_patches != NULL, so that the
server doesn't try to send patches which will just fail
again. At least currently, the client also clobbers the
file and tells the server it is lost, which also will get
a full file instead of a patch, but it seems clean to omit
-u. */
if (failed_patches == NULL)
if (failed_patches_count == 0)
{
unsigned int flags = 0;
/* 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.
We don't send -u if failed_patches != NULL, so that the
server doesn't try to send patches which will just fail
again. At least currently, the client also clobbers the
file and tells the server it is lost, which also will get
a full file instead of a patch, but it seems clean to omit
-u. */
if (supported_request ("update-patches"))
send_arg ("-u");
}
if (failed_patches == NULL)
{
if (update_build_dirs)
flags |= SEND_BUILD_DIRS;
if (toss_local_changes) {
flags |= SEND_NO_CONTENTS;
flags |= BACKUP_MODIFIED_FILES;
}
/* If noexec, probably could be setting SEND_NO_CONTENTS.
Same caveats as for "cvs status" apply. */
send_files (argc, argv, local, aflag,
update_build_dirs ? SEND_BUILD_DIRS : 0);
send_files (argc, argv, local, aflag, flags);
send_file_names (argc, argv, SEND_EXPAND_WILD);
}
else
@ -311,11 +325,9 @@ update (argc, argv)
send_files (failed_patches_count, failed_patches, local,
aflag, update_build_dirs ? SEND_BUILD_DIRS : 0);
send_file_names (failed_patches_count, failed_patches, 0);
free_names (&failed_patches_count, failed_patches);
}
failed_patches = NULL;
failed_patches_count = 0;
send_to_server ("update\012", 0);
status = get_responses_and_close ();
@ -334,13 +346,15 @@ update (argc, argv)
conflict-and-patch-failed case. */
if (status != 0
&& (failed_patches == NULL || pass > 1))
&& (failed_patches_count == 0 || pass > 1))
{
if (failed_patches_count > 0)
free_names (&failed_patches_count, failed_patches);
return status;
}
++pass;
} while (failed_patches != NULL);
} while (failed_patches_count > 0);
return 0;
}
@ -366,15 +380,20 @@ update (argc, argv)
error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
#ifdef SERVER_SUPPORT
if (server_active)
server_clear_entstat (".", Name_Repository (NULL, NULL));
{
char *repos = Name_Repository (NULL, NULL);
server_clear_entstat (".", repos);
free (repos);
}
#endif
}
/* keep the CVS/Tag file current with the specified arguments */
if (aflag || tag || date)
{
WriteTag ((char *) NULL, tag, date, 0,
".", Name_Repository (NULL, NULL));
char *repos = Name_Repository (NULL, NULL);
WriteTag ((char *) NULL, tag, date, 0, ".", repos);
free (repos);
rewrite_tag = 1;
nonbranch = 0;
}
@ -484,17 +503,11 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
argc, argv, local, which, aflag, 1,
preload_update_dir, 1);
/* see if we need to sleep before returning */
/* see if we need to sleep before returning to avoid time-stamp races */
if (last_register_time)
{
time_t now;
for (;;)
{
(void) time (&now);
if (now != last_register_time) break;
sleep (1); /* to avoid time-stamp races */
}
while (time ((time_t *) NULL) == last_register_time)
sleep (1);
}
return (err);
@ -641,54 +654,82 @@ update_fileproc (callerdat, finfo)
break;
case T_MODIFIED: /* locally modified */
retval = 0;
if (vers->ts_conflict)
{
char *filestamp;
int retcode;
/*
* If the timestamp has changed and no conflict indicators
* are found, it isn't a 'C' any more.
*/
if (toss_local_changes)
{
char *bakname;
bakname = backup_file (finfo->file, vers->vn_user);
/* This behavior is sufficiently unexpected to
justify overinformativeness, I think. */
#ifdef SERVER_SUPPORT
if (server_active)
retcode = vers->ts_conflict[0] != '=';
else {
filestamp = time_stamp (finfo->file);
retcode = strcmp (vers->ts_conflict, filestamp);
free (filestamp);
}
if ((! really_quiet) && (! server_active))
#else /* ! SERVER_SUPPORT */
if (! really_quiet)
#endif /* SERVER_SUPPORT */
(void) printf ("(Locally modified %s moved to %s)\n",
finfo->file, bakname);
free (bakname);
/* The locally modified file is still present, but
it will be overwritten by the repository copy
after this. */
status = T_CHECKOUT;
retval = checkout_file (finfo, vers, 0, 0, 1);
}
else
{
if (vers->ts_conflict)
{
char *filestamp;
int retcode;
/*
* If the timestamp has changed and no
* conflict indicators are found, it isn't a
* 'C' any more.
*/
#ifdef SERVER_SUPPORT
if (server_active)
retcode = vers->ts_conflict[0] != '=';
else
{
filestamp = time_stamp (finfo->file);
retcode = strcmp (vers->ts_conflict, filestamp);
free (filestamp);
}
#else
filestamp = time_stamp (finfo->file);
retcode = strcmp (vers->ts_conflict, filestamp);
free (filestamp);
filestamp = time_stamp (finfo->file);
retcode = strcmp (vers->ts_conflict, filestamp);
free (filestamp);
#endif
if (retcode)
{
/* The timestamps differ. But if there are conflict
markers print 'C' anyway. */
retcode = !file_has_markers (finfo);
}
if (retcode)
{
/* The timestamps differ. But if there
are conflict markers print 'C' anyway. */
retcode = !file_has_markers (finfo);
}
if (!retcode)
{
write_letter (finfo, 'C');
retval = 1;
}
else
{
/* Reregister to clear conflict flag. */
Register (finfo->entries, finfo->file, vers->vn_rcs, vers->ts_rcs,
vers->options, vers->tag,
vers->date, (char *)0);
}
}
if (!retval)
{
write_letter (finfo, 'M');
retval = 0;
}
if (!retcode)
{
write_letter (finfo, 'C');
retval = 1;
}
else
{
/* Reregister to clear conflict flag. */
Register (finfo->entries, finfo->file,
vers->vn_rcs, vers->ts_rcs,
vers->options, vers->tag,
vers->date, (char *)0);
}
}
if (!retval)
{
write_letter (finfo, 'M');
retval = 0;
}
}
break;
#ifdef SERVER_SUPPORT
case T_PATCH: /* needs patch */
@ -928,7 +969,8 @@ update_dirent_proc (callerdat, dir, repository, update_dir, entries)
/* This is a guess. We will rewrite it later
via WriteTag. */
0,
0);
0,
1);
rewrite_tag = 1;
nonbranch = 0;
Subdir_Register (entries, (char *) NULL, dir);
@ -1014,6 +1056,10 @@ update_dirleave_proc (callerdat, dir, err, update_dir, entries)
{
FILE *fp;
/* Delete the ignore list if it hasn't already been done. */
if (ignlist)
dellist (&ignlist);
/* If we set the tag or date for a new subdirectory in
update_dirent_proc, and we're now done with that subdirectory,
undo the tag/date setting. Note that we know that the tag and
@ -1059,6 +1105,7 @@ update_dirleave_proc (callerdat, dir, err, update_dir, entries)
cvs_output (": Executing '", 0);
run_print (stdout);
cvs_output ("'\n", 0);
cvs_flushout ();
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
}
else if (ferror (fp))
@ -2049,7 +2096,7 @@ join_file (finfo, vers)
Vers_TS *vers;
{
char *backup;
char *options;
char *t_options;
int status;
char *rev1;
@ -2284,6 +2331,13 @@ join_file (finfo, vers)
xvers = Version_TS (finfo, vers->options, jrev2, jdate2, 1, 0);
/* Reset any keyword expansion option. Otherwise, when a
command like `cvs update -kk -jT1 -jT2' creates a new file
(because a file had the T2 tag, but not T1), the subsequent
commit of that just-added file effectively would set the
admin `-kk' option for that file in the repository. */
options = NULL;
/* FIXME: If checkout_file fails, we should arrange to
return a non-zero exit status. */
status = checkout_file (finfo, xvers, 1, 0, 1);
@ -2326,11 +2380,11 @@ join_file (finfo, vers)
if (jdate2 != NULL)
error (0, 0,
"file %s is present in revision %s as of %s",
"file %s does not exist, but is present in revision %s as of %s",
finfo->fullname, jrev2, jdate2);
else
error (0, 0,
"file %s is present in revision %s",
"file %s does not exist, but is present in revision %s",
finfo->fullname, jrev2);
/* FIXME: Should we arrange to return a non-zero exit status? */
@ -2372,10 +2426,10 @@ join_file (finfo, vers)
copy_file (finfo->file, backup);
xchmod (finfo->file, 1);
options = vers->options;
t_options = vers->options;
#if 0
if (*options == '\0')
options = "-kk"; /* to ignore keyword expansions */
if (*t_options == '\0')
t_options = "-kk"; /* to ignore keyword expansions */
#endif
/* If the source of the merge is the same as the working file
@ -2393,12 +2447,12 @@ join_file (finfo, vers)
/* This is because of the worry below about $Name. If that
isn't a problem, I suspect this code probably works for
text files too. */
&& (strcmp (options, "-kb") == 0
&& (strcmp (t_options, "-kb") == 0
|| wrap_merge_is_copy (finfo->file)))
{
/* FIXME: what about nametag? What does RCS_merge do with
$Name? */
if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, options,
if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, t_options,
RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
status = 2;
else
@ -2422,7 +2476,7 @@ join_file (finfo, vers)
print. */
write_letter (finfo, 'U');
}
else if (strcmp (options, "-kb") == 0
else if (strcmp (t_options, "-kb") == 0
|| wrap_merge_is_copy (finfo->file)
|| special_file_mismatch (finfo, rev1, rev2))
{
@ -2432,7 +2486,7 @@ join_file (finfo, vers)
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. */
if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, options,
if (RCS_checkout (finfo->rcs, finfo->file, rev2, NULL, t_options,
RUN_TTY, (RCSCHECKOUTPROC)0, NULL) != 0)
status = 2;
else
@ -2463,7 +2517,7 @@ join_file (finfo, vers)
}
else
status = RCS_merge (finfo->rcs, vers->srcfile->path, finfo->file,
options, rev1, rev2);
t_options, rev1, rev2);
if (status != 0 && status != 1)
{
@ -2494,9 +2548,9 @@ join_file (finfo, vers)
(void) time (&last_register_time);
cp = time_stamp (finfo->file);
}
Register (finfo->entries, finfo->file, vers->vn_rcs,
"Result of merge", vers->options, vers->tag,
vers->date, cp);
Register (finfo->entries, finfo->file,
vers->vn_rcs ? vers->vn_rcs : "0", "Result of merge",
vers->options, vers->tag, vers->date, cp);
if (cp)
free(cp);
}
@ -2544,8 +2598,8 @@ special_file_mismatch (finfo, rev1, rev2)
dev_t rev1_dev, rev2_dev;
char *rev1_symlink = NULL;
char *rev2_symlink = NULL;
List *rev1_hardlinks;
List *rev2_hardlinks;
List *rev1_hardlinks = NULL;
List *rev2_hardlinks = NULL;
int check_uids, check_gids, check_modes;
int result;
@ -2574,6 +2628,7 @@ special_file_mismatch (finfo, rev1, rev2)
rev1_symlink = xreadlink (finfo->file);
else
{
#ifdef HAVE_ST_RDEV
if (CVS_LSTAT (finfo->file, &sb) < 0)
error (1, errno, "could not get file information for %s",
finfo->file);
@ -2582,6 +2637,10 @@ special_file_mismatch (finfo, rev1, rev2)
rev1_mode = sb.st_mode;
if (S_ISBLK (rev1_mode) || S_ISCHR (rev1_mode))
rev1_dev = sb.st_rdev;
#else
error (1, 0, "cannot handle device files on this system (%s)",
finfo->file);
#endif
}
rev1_hardlinks = list_linked_files_on_disk (finfo->file);
}
@ -2647,6 +2706,7 @@ special_file_mismatch (finfo, rev1, rev2)
rev2_symlink = xreadlink (finfo->file);
else
{
#ifdef HAVE_ST_RDEV
if (CVS_LSTAT (finfo->file, &sb) < 0)
error (1, errno, "could not get file information for %s",
finfo->file);
@ -2655,6 +2715,10 @@ special_file_mismatch (finfo, rev1, rev2)
rev2_mode = sb.st_mode;
if (S_ISBLK (rev2_mode) || S_ISCHR (rev2_mode))
rev2_dev = sb.st_rdev;
#else
error (1, 0, "cannot handle device files on this system (%s)",
finfo->file);
#endif
}
rev2_hardlinks = list_linked_files_on_disk (finfo->file);
}

View File

@ -87,22 +87,17 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
vers_ts->vn_user = xstrdup (entdata->version);
vers_ts->ts_rcs = xstrdup (entdata->timestamp);
vers_ts->ts_conflict = xstrdup (entdata->conflict);
if (!tag)
if (!(tag || date) && !(sdtp && sdtp->aflag))
{
if (!(sdtp && sdtp->aflag))
vers_ts->tag = xstrdup (entdata->tag);
}
if (!date)
{
if (!(sdtp && sdtp->aflag))
vers_ts->date = xstrdup (entdata->date);
vers_ts->tag = xstrdup (entdata->tag);
vers_ts->date = xstrdup (entdata->date);
}
vers_ts->entdata = entdata;
}
/* Even if we don't have an "entries line" as such
(vers_ts->entdata), we want to pick up options which could
have been from a Kopt protocol request. */
if (!options || (options && *options == '\0'))
if (!options || *options == '\0')
{
if (!(sdtp && sdtp->aflag))
vers_ts->options = xstrdup (entdata->options);
@ -126,6 +121,8 @@ Version_TS (finfo, options, tag, date, force_tag_match, set_time)
char *rcsexpand = RCS_getexpand (finfo->rcs);
if (rcsexpand != NULL)
{
if (vers_ts->options != NULL)
free (vers_ts->options);
vers_ts->options = xmalloc (strlen (rcsexpand) + 3);
strcpy (vers_ts->options, "-k");
strcat (vers_ts->options, rcsexpand);

View File

@ -12,7 +12,7 @@
#include "cvs.h"
char *version_string = "\nConcurrent Versions System (CVS) 1.10.7";
char *version_string = "Concurrent Versions System (CVS) 1.11";
#ifdef CLIENT_SUPPORT
#ifdef SERVER_SUPPORT
@ -27,3 +27,49 @@ char *config_string = " (server)\n";
char *config_string = "\n";
#endif
#endif
static const char *const version_usage[] =
{
"Usage: %s %s\n",
NULL
};
int
version (argc, argv)
int argc;
char **argv;
{
int err = 0;
if (argc == -1)
usage (version_usage);
#ifdef CLIENT_SUPPORT
if (client_active)
(void) fputs ("Client: ", stdout);
#endif
/* Having the year here is a good idea, so people have
some idea of how long ago their version of CVS was
released. */
(void) fputs (version_string, stdout);
(void) fputs (config_string, stdout);
#ifdef CLIENT_SUPPORT
if (client_active)
{
(void) fputs ("Server: ", stdout);
start_server ();
if (supported_request ("version"))
send_to_server ("version\012", 0);
else
{
send_to_server ("noop\012", 0);
fputs ("(unknown)\n", stdout);
}
err = get_responses_and_close ();
}
#endif
return err;
}

View File

@ -473,6 +473,7 @@ watchers_fileproc (callerdat, finfo)
cvs_output ("\n", 1);
}
out:;
free (them);
return 0;
}

View File

@ -467,9 +467,9 @@ gunzip_and_write (fd, fullname, buf, size)
if (buf[3] & 4)
pos += buf[pos] + (buf[pos + 1] << 8) + 2;
if (buf[3] & 8)
pos += strlen (buf + pos) + 1;
pos += strlen ((char *) buf + pos) + 1;
if (buf[3] & 16)
pos += strlen (buf + pos) + 1;
pos += strlen ((char *) buf + pos) + 1;
if (buf[3] & 2)
pos += 2;